From 5523e09ab252966533934ba05be5d47c5520b72d Mon Sep 17 00:00:00 2001 From: Dustin Wilson Date: Wed, 29 Dec 2021 16:26:39 -0600 Subject: [PATCH] More tests, started documentation --- README.md | 116 ++++++- composer.lock | 90 +++--- lib/HTMLElement.php | 9 +- lib/Node.php | 2 +- tests/cases/TestDocument.php | 42 +++ tests/cases/TestHTMLElement.php | 452 +++++++++++++++++++++++++++ tests/cases/TestHTMLOrSVGElement.php | 29 ++ tests/phpunit.dist.xml | 1 + vendor-bin/phpunit/composer.lock | 19 +- vendor-bin/robo/composer.lock | 189 +++++------ 10 files changed, 799 insertions(+), 150 deletions(-) create mode 100644 tests/cases/TestHTMLOrSVGElement.php diff --git a/README.md b/README.md index 7c3f36f..975a718 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,94 @@ Modern DOM library written in PHP for HTML documents. This library is an attempt ## Usage ## -Coming soon +Full documentation for most of the library shouldn't be necessary because it largely follows the specification, but because of how the library is to be used there are a few things that are glaringly different. These will be outlined below. -## Examples ## +### MensBeam\HTML\DOM\Document ### + +```php +namespace MensBeam\HTML\DOM; + +partial class Document { + use DocumentOrElement, NonElementParentNode, ParentNode, XPathEvaluatorBase; + + public function __construct( + string $source = null, + ?string $charset = null + ); + + public function serialize( + ?Node $node = null, + array $config = [] + ): string; +} +``` + +#### MensBeam\HTML\DOM\Document::__construct #### + +Creates a new `MensBeam\HTML\DOM\Document` object. + +* `source`: A string representing an HTML document to be parsed. +* `charset`: Character set to be used as the encoding for the document. If a document is parsed its default is 'windows-1251', otherwise 'UTF-8'. + +#### MensBeam\HTML\DOM\Document::serialize #### + +Converts a node to a string. + +* `node`: A node within the document to serialize, defaults to the document itself. +* `config`: A configuration array with the possible keys and value types being: + - `booleanAttributeValues` (`bool|null`): Whether to include the values of boolean attributes on HTML elements during serialization. Per the standard this is `true` by default + - `foreignVoidEndTags` (`bool|null`): Whether to print the end tags of foreign void elements rather than self-closing their start tags. Per the standard this is `true` by default + - `indentStep` (`int|null`): The number of spaces or tabs (depending on setting of indentStep) to indent at each step. This is `1` by default and has no effect unless `reformatWhitespace` is `true` + - `indentWithSpaces` (`bool|null`): Whether to use spaces or tabs to indent. This is `true` by default and has no effect unless `reformatWhitespace` is `true` + - `reformatWhitespace` (`bool|null`): Whether to reformat whitespace (pretty-print) or not. This is `false` by default + +### MensBeam\HTML\DOM\Node ### + +```php +namespace MensBeam\HTML\DOM; + +partial abstract class Node implements \Stringable { + // Common namespace constants provided for convenience + public const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; + public const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; + public const SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; + public const XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink'; + public const XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace'; + public const XMLNS_NAMESPACE = 'http://www.w3.org/2000/xmlns/'; + + // Used with MensBeam\HTML\DOM\ParentNode::walk + public const WALK_ACCEPT = 0x01; + public const WALK_REJECT = 0x02; + public const WALK_SKIP_CHILDREN = 0x04; + public const WALK_STOP = 0x08; +} +``` + +### MensBeam\HTML\DOM\ParentNode ### + +```php +namespace MensBeam\HTML\DOM; + +partial trait ParentNode { + public function walk( + ?\Closure $filter = null, + bool $includeReferenceNode = false + ): \Generator; +} +``` + +#### MensBeam\HTML\DOM\ParentNode::walk #### + +Applies the callback filter while walking down the DOM tree and yields nodes matching the filter in a generator. + +* `filter`: A callback method to filter the DOM tree. Must return only the following values: + - `Node::WALK_ACCEPT`: Accept the node. + - `Node::WALK_REJECT`: Reject the node. + - `Node::WALK_SKIP_CHILDREN`: Skip the node's children. + - `Node::WALK_STOP`: Stop the walker. +* `includeReferenceNode`: Include `$this` when walking down the tree. + +### Examples ### - Creating a new document: @@ -40,6 +125,33 @@ Coming soon $d->load('Ook

Ook!

'); ``` +- Serializing a document: + + ```php + use MensBeam\HTML\DOM; + + $d = new Document(''); + echo $d->serialize(); + ``` + + or: + + ```php + use MensBeam\HTML\DOM; + + $d = new Document(''); + echo $d; + ``` + +- Serializing a document (pretty printing): + + ```php + use MensBeam\HTML\DOM; + + $d = new Document(''); + echo $d->serialize($d, [ 'reformatWhitespace' => true ]); + ``` + ## Limitations & Differences from Specification ## The primary aim of this library is accuracy. However, due either to limitations imposed by PHP's DOM, by assumptions made by the specification that aren't applicable to a PHP library, or simply because of impracticality some changes have needed to be made. These are as follows: diff --git a/composer.lock b/composer.lock index 2c32d6f..77d9072 100644 --- a/composer.lock +++ b/composer.lock @@ -12,7 +12,7 @@ "source": { "type": "git", "url": "mensbeam-gitea:MensBeam/Framework.git", - "reference": "bf7515f4c5d02ce9919a92a27812af7587a4700e" + "reference": "c9aa6b9659c1607a1242d585aa41caf0aba33e5f" }, "require": { "php": ">=7.4" @@ -55,7 +55,7 @@ } ], "description": "Common classes and traits used in many Mensbeam projects", - "time": "2021-10-21T14:20:02+00:00" + "time": "2021-12-29T16:07:18+00:00" }, { "name": "mensbeam/html-parser", @@ -293,16 +293,16 @@ }, { "name": "symfony/css-selector", - "version": "v5.4.0", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "44b933f98bb4b5220d10bed9ce5662f8c2d13dcc" + "reference": "cfcbee910e159df402603502fe387e8b677c22fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/44b933f98bb4b5220d10bed9ce5662f8c2d13dcc", - "reference": "44b933f98bb4b5220d10bed9ce5662f8c2d13dcc", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/cfcbee910e159df402603502fe387e8b677c22fd", + "reference": "cfcbee910e159df402603502fe387e8b677c22fd", "shasum": "" }, "require": { @@ -339,7 +339,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v5.4.0" + "source": "https://github.com/symfony/css-selector/tree/v5.4.2" }, "funding": [ { @@ -355,7 +355,7 @@ "type": "tidelift" } ], - "time": "2021-09-09T08:06:01+00:00" + "time": "2021-12-16T21:58:21+00:00" }, { "name": "symfony/polyfill-php80", @@ -1445,16 +1445,16 @@ }, { "name": "symfony/console", - "version": "v5.4.1", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "9130e1a0fc93cb0faadca4ee917171bd2ca9e5f4" + "reference": "a2c6b7ced2eb7799a35375fb9022519282b5405e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/9130e1a0fc93cb0faadca4ee917171bd2ca9e5f4", - "reference": "9130e1a0fc93cb0faadca4ee917171bd2ca9e5f4", + "url": "https://api.github.com/repos/symfony/console/zipball/a2c6b7ced2eb7799a35375fb9022519282b5405e", + "reference": "a2c6b7ced2eb7799a35375fb9022519282b5405e", "shasum": "" }, "require": { @@ -1524,7 +1524,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.1" + "source": "https://github.com/symfony/console/tree/v5.4.2" }, "funding": [ { @@ -1540,7 +1540,7 @@ "type": "tidelift" } ], - "time": "2021-12-09T11:22:43+00:00" + "time": "2021-12-20T16:11:12+00:00" }, { "name": "symfony/deprecation-contracts", @@ -1611,16 +1611,16 @@ }, { "name": "symfony/http-foundation", - "version": "v5.4.1", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "5dad3780023a707f4c24beac7d57aead85c1ce3c" + "reference": "ce952af52877eaf3eab5d0c08cc0ea865ed37313" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5dad3780023a707f4c24beac7d57aead85c1ce3c", - "reference": "5dad3780023a707f4c24beac7d57aead85c1ce3c", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ce952af52877eaf3eab5d0c08cc0ea865ed37313", + "reference": "ce952af52877eaf3eab5d0c08cc0ea865ed37313", "shasum": "" }, "require": { @@ -1664,7 +1664,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.1" + "source": "https://github.com/symfony/http-foundation/tree/v5.4.2" }, "funding": [ { @@ -1680,20 +1680,20 @@ "type": "tidelift" } ], - "time": "2021-12-09T12:46:57+00:00" + "time": "2021-12-28T17:15:56+00:00" }, { "name": "symfony/mime", - "version": "v5.4.0", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "d4365000217b67c01acff407573906ff91bcfb34" + "reference": "1bfd938cf9562822c05c4d00e8f92134d3c8e42d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/d4365000217b67c01acff407573906ff91bcfb34", - "reference": "d4365000217b67c01acff407573906ff91bcfb34", + "url": "https://api.github.com/repos/symfony/mime/zipball/1bfd938cf9562822c05c4d00e8f92134d3c8e42d", + "reference": "1bfd938cf9562822c05c4d00e8f92134d3c8e42d", "shasum": "" }, "require": { @@ -1747,7 +1747,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.4.0" + "source": "https://github.com/symfony/mime/tree/v5.4.2" }, "funding": [ { @@ -1763,7 +1763,7 @@ "type": "tidelift" } ], - "time": "2021-11-23T10:19:22+00:00" + "time": "2021-12-28T17:15:56+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2420,16 +2420,16 @@ }, { "name": "symfony/process", - "version": "v5.4.0", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "5be20b3830f726e019162b26223110c8f47cf274" + "reference": "2b3ba8722c4aaf3e88011be5e7f48710088fb5e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/5be20b3830f726e019162b26223110c8f47cf274", - "reference": "5be20b3830f726e019162b26223110c8f47cf274", + "url": "https://api.github.com/repos/symfony/process/zipball/2b3ba8722c4aaf3e88011be5e7f48710088fb5e4", + "reference": "2b3ba8722c4aaf3e88011be5e7f48710088fb5e4", "shasum": "" }, "require": { @@ -2462,7 +2462,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.0" + "source": "https://github.com/symfony/process/tree/v5.4.2" }, "funding": [ { @@ -2478,7 +2478,7 @@ "type": "tidelift" } ], - "time": "2021-11-28T15:25:38+00:00" + "time": "2021-12-27T21:01:00+00:00" }, { "name": "symfony/service-contracts", @@ -2564,16 +2564,16 @@ }, { "name": "symfony/string", - "version": "v6.0.1", + "version": "v6.0.2", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "0cfed595758ec6e0a25591bdc8ca733c1896af32" + "reference": "bae261d0c3ac38a1f802b4dfed42094296100631" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/0cfed595758ec6e0a25591bdc8ca733c1896af32", - "reference": "0cfed595758ec6e0a25591bdc8ca733c1896af32", + "url": "https://api.github.com/repos/symfony/string/zipball/bae261d0c3ac38a1f802b4dfed42094296100631", + "reference": "bae261d0c3ac38a1f802b4dfed42094296100631", "shasum": "" }, "require": { @@ -2629,7 +2629,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.0.1" + "source": "https://github.com/symfony/string/tree/v6.0.2" }, "funding": [ { @@ -2645,20 +2645,20 @@ "type": "tidelift" } ], - "time": "2021-12-08T15:13:44+00:00" + "time": "2021-12-16T22:13:01+00:00" }, { "name": "symfony/yaml", - "version": "v5.4.0", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "034ccc0994f1ae3f7499fa5b1f2e75d5e7a94efc" + "reference": "b9eb163846a61bb32dfc147f7859e274fab38b58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/034ccc0994f1ae3f7499fa5b1f2e75d5e7a94efc", - "reference": "034ccc0994f1ae3f7499fa5b1f2e75d5e7a94efc", + "url": "https://api.github.com/repos/symfony/yaml/zipball/b9eb163846a61bb32dfc147f7859e274fab38b58", + "reference": "b9eb163846a61bb32dfc147f7859e274fab38b58", "shasum": "" }, "require": { @@ -2704,7 +2704,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.4.0" + "source": "https://github.com/symfony/yaml/tree/v5.4.2" }, "funding": [ { @@ -2720,7 +2720,7 @@ "type": "tidelift" } ], - "time": "2021-11-28T15:25:38+00:00" + "time": "2021-12-16T21:58:21+00:00" }, { "name": "webuni/front-matter", @@ -2808,5 +2808,5 @@ "ext-dom": "*" }, "platform-dev": [], - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.1.0" } diff --git a/lib/HTMLElement.php b/lib/HTMLElement.php index 354ffb1..a2c7df7 100644 --- a/lib/HTMLElement.php +++ b/lib/HTMLElement.php @@ -437,7 +437,7 @@ class HTMLElement extends Element { return ($this->getAttribute('spellcheck') === 'true'); } - protected function __set_spellcheck(bool $value): bool { + protected function __set_spellcheck(bool $value): void { # On setting, if the new value is true, then the element's spellcheck content # attribute must be set to the literal string "true", otherwise it must be set # to the literal string "false". @@ -468,7 +468,7 @@ class HTMLElement extends Element { # element's translation mode is in the same state as its parent element's, if # any, or in the translate-enabled state, if the element is a document element. - $value = strtolower($this->getAttribute('translate')); + $value = strtolower($this->getAttribute('translate') ?? ''); if ($value === 'yes') { return true; } elseif ($value === 'no') { @@ -478,7 +478,10 @@ class HTMLElement extends Element { $n = $this->innerNode; $doc = $n->ownerDocument; while ($n = $n->parentNode) { - if ($n->getAttribute('translate') === 'yes' && $doc->getWrapperNode($n) instanceof HTMLElement) { + // This looks weird but it's faster to check for the method here first because + // getting a wrapper node causes a wrapper element to be created if it doesn't + // already exist. Don't want to create unnecessary wrappers. + if (method_exists($n, 'getAttribute') && $n->getAttribute('translate') === 'yes' && $doc->getWrapperNode($n) instanceof HTMLElement) { return true; } } diff --git a/lib/Node.php b/lib/Node.php index 268e4bb..cb7e112 100644 --- a/lib/Node.php +++ b/lib/Node.php @@ -16,7 +16,7 @@ use MensBeam\HTML\DOM\Inner\{ }; -abstract class Node { +abstract class Node implements \Stringable { use MagicProperties, NameCoercion; // Namespace constants diff --git a/tests/cases/TestDocument.php b/tests/cases/TestDocument.php index fae4133..f33ba67 100644 --- a/tests/cases/TestDocument.php +++ b/tests/cases/TestDocument.php @@ -619,6 +619,48 @@ class TestDocument extends \PHPUnit\Framework\TestCase { } + /** + * @covers \MensBeam\HTML\DOM\Document::__get_dir + * @covers \MensBeam\HTML\DOM\Document::__set_dir + * + * @covers \MensBeam\HTML\DOM\Attr::__get_value + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::__get_documentElement + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Element::__get_localName + * @covers \MensBeam\HTML\DOM\Element::__get_namespaceURI + * @covers \MensBeam\HTML\DOM\Element::__get_prefix + * @covers \MensBeam\HTML\DOM\Element::__get_tagName + * @covers \MensBeam\HTML\DOM\Element::getAttribute + * @covers \MensBeam\HTML\DOM\Element::getAttributeNode + * @covers \MensBeam\HTML\DOM\Element::setAttribute + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_dir + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_dir + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ + public function testProperty_dir(): void { + $d = new Document(''); + $this->assertSame('ltr', $d->dir); + $d->dir = 'bullshit'; + $this->assertSame('', $d->dir); + } + + /** * @covers \MensBeam\HTML\DOM\Document::__get_doctype * diff --git a/tests/cases/TestHTMLElement.php b/tests/cases/TestHTMLElement.php index 348fc54..54ae237 100644 --- a/tests/cases/TestHTMLElement.php +++ b/tests/cases/TestHTMLElement.php @@ -16,6 +16,35 @@ use MensBeam\HTML\DOM\{ /** @covers \MensBeam\HTML\DOM\HTMLElement */ class TestHTMLElement extends \PHPUnit\Framework\TestCase { + /** + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_accessKey + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_accessKey + * + * @covers \MensBeam\HTML\DOM\Attr::__get_value + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Element::__get_namespaceURI + * @covers \MensBeam\HTML\DOM\Element::getAttribute + * @covers \MensBeam\HTML\DOM\Element::getAttributeNode + * @covers \MensBeam\HTML\DOM\Element::setAttribute + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\NonElementParentNode::getElementById + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ public function testProperty_accessKey(): void { $d = new Document(''); $ook = $d->getElementById('ook'); @@ -24,6 +53,39 @@ class TestHTMLElement extends \PHPUnit\Framework\TestCase { $this->assertSame('e', $ook->accessKey); } + + /** + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_autocapitalize + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_autocapitalize + * + * @covers \MensBeam\HTML\DOM\Collection::__construct + * @covers \MensBeam\HTML\DOM\Collection::item + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DocumentOrElement::getElementsByTagName + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Element::__get_namespaceURI + * @covers \MensBeam\HTML\DOM\Element::removeAttribute + * @covers \MensBeam\HTML\DOM\Element::setAttribute + * @covers \MensBeam\HTML\DOM\HTMLCollection::item + * @covers \MensBeam\HTML\DOM\HTMLCollection::offsetGet + * @covers \MensBeam\HTML\DOM\HTMLElement::autoCapitalizationHint + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ public function testProperty_autocapitalize(): void { $d = new Document('
'); $ook = $d->getElementsByTagName('input')[0]; @@ -41,6 +103,46 @@ class TestHTMLElement extends \PHPUnit\Framework\TestCase { $this->assertSame('sentences', $ook->autocapitalize); } + + /** + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_contentEditable + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_contentEditable + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_isContentEditable + * + * @covers \MensBeam\HTML\DOM\Attr::__get_value + * @covers \MensBeam\HTML\DOM\Collection::__construct + * @covers \MensBeam\HTML\DOM\Collection::item + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::__get_body + * @covers \MensBeam\HTML\DOM\Document::__get_designMode + * @covers \MensBeam\HTML\DOM\Document::__set_designMode + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DocumentOrElement::getElementsByTagName + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Element::__get_namespaceURI + * @covers \MensBeam\HTML\DOM\Element::getAttribute + * @covers \MensBeam\HTML\DOM\Element::getAttributeNode + * @covers \MensBeam\HTML\DOM\Element::hasAttribute + * @covers \MensBeam\HTML\DOM\Element::removeAttribute + * @covers \MensBeam\HTML\DOM\Element::setAttribute + * @covers \MensBeam\HTML\DOM\HTMLCollection::item + * @covers \MensBeam\HTML\DOM\HTMLCollection::offsetGet + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ public function testProperty_contentEditable_isContentEditable(): void { $d = new Document('
'); $div = $d->getElementsByTagName('div')[0]; @@ -62,8 +164,35 @@ class TestHTMLElement extends \PHPUnit\Framework\TestCase { $d->designMode = 'on'; $this->assertTrue($div->isContentEditable); + $d->body->contentEditable = 'false'; + $d->designMode = 'off'; + $this->assertFalse($div->isContentEditable); } + + /** + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_contentEditable + * + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::__get_documentElement + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DOMException::__construct + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ public function testProperty_contentEditable__errors(): void { $this->expectException(DOMException::class); $this->expectExceptionCode(DOMException::SYNTAX_ERROR); @@ -71,6 +200,36 @@ class TestHTMLElement extends \PHPUnit\Framework\TestCase { $d->documentElement->contentEditable = 'fail'; } + + /** + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_dir + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_dir + * + * @covers \MensBeam\HTML\DOM\Attr::__get_value + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::__get_documentElement + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Element::__get_namespaceURI + * @covers \MensBeam\HTML\DOM\Element::getAttribute + * @covers \MensBeam\HTML\DOM\Element::getAttributeNode + * @covers \MensBeam\HTML\DOM\Element::setAttribute + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ public function testProperty_dir(): void { $d = new Document(''); $html = $d->documentElement; @@ -79,6 +238,45 @@ class TestHTMLElement extends \PHPUnit\Framework\TestCase { $this->assertSame('', $html->dir); } + + /** + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_draggable + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_draggable + * + * @covers \MensBeam\HTML\DOM\Attr::__get_value + * @covers \MensBeam\HTML\DOM\Collection::__construct + * @covers \MensBeam\HTML\DOM\Collection::item + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DocumentOrElement::getElementsByTagName + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Element::__get_localName + * @covers \MensBeam\HTML\DOM\Element::__get_namespaceURI + * @covers \MensBeam\HTML\DOM\Element::__get_prefix + * @covers \MensBeam\HTML\DOM\Element::__get_tagName + * @covers \MensBeam\HTML\DOM\Element::getAttribute + * @covers \MensBeam\HTML\DOM\Element::getAttributeNode + * @covers \MensBeam\HTML\DOM\Element::hasAttribute + * @covers \MensBeam\HTML\DOM\Element::removeAttribute + * @covers \MensBeam\HTML\DOM\Element::setAttribute + * @covers \MensBeam\HTML\DOM\HTMLCollection::item + * @covers \MensBeam\HTML\DOM\HTMLCollection::offsetGet + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ public function testProperty_draggable(): void { $d = new Document('
'); $img = $d->getElementsByTagName('img')[0]; @@ -102,6 +300,36 @@ class TestHTMLElement extends \PHPUnit\Framework\TestCase { $this->assertTrue($object->draggable); } + + /** + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_enterKeyHint + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_enterKeyHint + * + * @covers \MensBeam\HTML\DOM\Attr::__get_value + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::__get_documentElement + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Element::__get_namespaceURI + * @covers \MensBeam\HTML\DOM\Element::getAttribute + * @covers \MensBeam\HTML\DOM\Element::getAttributeNode + * @covers \MensBeam\HTML\DOM\Element::setAttribute + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ public function testProperty_enterKeyHint(): void { $d = new Document(''); $html = $d->documentElement; @@ -112,6 +340,41 @@ class TestHTMLElement extends \PHPUnit\Framework\TestCase { $this->assertSame('done', $html->enterKeyHint); } + + /** + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_hidden + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_hidden + * + * @covers \MensBeam\HTML\DOM\Collection::__construct + * @covers \MensBeam\HTML\DOM\Collection::item + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::__get_documentElement + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DocumentOrElement::getElementsByTagName + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Element::__get_namespaceURI + * @covers \MensBeam\HTML\DOM\Element::getAttributeNode + * @covers \MensBeam\HTML\DOM\Element::hasAttribute + * @covers \MensBeam\HTML\DOM\Element::removeAttribute + * @covers \MensBeam\HTML\DOM\Element::setAttribute + * @covers \MensBeam\HTML\DOM\HTMLCollection::item + * @covers \MensBeam\HTML\DOM\HTMLCollection::offsetGet + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ public function testProperty_hidden(): void { $d = new Document('
'); $div = $d->getElementsByTagName('div')[0]; @@ -123,6 +386,36 @@ class TestHTMLElement extends \PHPUnit\Framework\TestCase { $this->assertTrue($div->hidden); } + + /** + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_lang + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_lang + * + * @covers \MensBeam\HTML\DOM\Attr::__get_value + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::__get_documentElement + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Element::__get_namespaceURI + * @covers \MensBeam\HTML\DOM\Element::getAttribute + * @covers \MensBeam\HTML\DOM\Element::getAttributeNode + * @covers \MensBeam\HTML\DOM\Element::setAttribute + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ public function testProperty_lang(): void { $d = new Document(''); $html = $d->documentElement; @@ -134,6 +427,7 @@ class TestHTMLElement extends \PHPUnit\Framework\TestCase { $this->assertSame('ook', $html->lang); } + /** * @covers \MensBeam\HTML\DOM\HTMLElement::__get_innerText * @covers \MensBeam\HTML\DOM\HTMLElement::__set_innerText @@ -202,6 +496,35 @@ class TestHTMLElement extends \PHPUnit\Framework\TestCase { } + /** + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_inputMode + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_inputMode + * + * @covers \MensBeam\HTML\DOM\Attr::__get_value + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::__get_documentElement + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Element::__get_namespaceURI + * @covers \MensBeam\HTML\DOM\Element::getAttribute + * @covers \MensBeam\HTML\DOM\Element::getAttributeNode + * @covers \MensBeam\HTML\DOM\Element::setAttribute + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ public function testProperty_inputMode(): void { $d = new Document(''); $html = $d->documentElement; @@ -238,4 +561,133 @@ class TestHTMLElement extends \PHPUnit\Framework\TestCase { $h = $d->createElement('html'); $h->outerText = 'fail'; } + + + /** + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_spellcheck + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_spellcheck + * + * @covers \MensBeam\HTML\DOM\Attr::__get_value + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::__get_documentElement + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Element::__get_namespaceURI + * @covers \MensBeam\HTML\DOM\Element::getAttribute + * @covers \MensBeam\HTML\DOM\Element::getAttributeNode + * @covers \MensBeam\HTML\DOM\Element::setAttribute + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ + public function testProperty_spellcheck(): void { + $d = new Document(''); + $html = $d->documentElement; + $this->assertFalse($html->spellcheck); + $html->spellcheck = true; + $this->assertTrue($html->spellcheck); + $html->spellcheck = false; + $this->assertFalse($html->spellcheck); + } + + + /** + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_title + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_title + * + * @covers \MensBeam\HTML\DOM\Attr::__get_value + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::__get_documentElement + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Element::__get_namespaceURI + * @covers \MensBeam\HTML\DOM\Element::getAttribute + * @covers \MensBeam\HTML\DOM\Element::getAttributeNode + * @covers \MensBeam\HTML\DOM\Element::setAttribute + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ + public function testProperty_title(): void { + $d = new Document(''); + $html = $d->documentElement; + $this->assertSame('', $html->title); + $html->title = 'ook'; + $this->assertSame('ook', $html->title); + } + + + /** + * @covers \MensBeam\HTML\DOM\HTMLElement::__get_translate + * @covers \MensBeam\HTML\DOM\HTMLElement::__set_translate + * + * @covers \MensBeam\HTML\DOM\Attr::__get_value + * @covers \MensBeam\HTML\DOM\Collection::__construct + * @covers \MensBeam\HTML\DOM\Collection::item + * @covers \MensBeam\HTML\DOM\Document::__construct + * @covers \MensBeam\HTML\DOM\Document::__get_documentElement + * @covers \MensBeam\HTML\DOM\Document::load + * @covers \MensBeam\HTML\DOM\DocumentOrElement::getElementsByTagName + * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct + * @covers \MensBeam\HTML\DOM\Element::__construct + * @covers \MensBeam\HTML\DOM\Element::__get_namespaceURI + * @covers \MensBeam\HTML\DOM\Element::getAttribute + * @covers \MensBeam\HTML\DOM\Element::getAttributeNode + * @covers \MensBeam\HTML\DOM\Element::removeAttribute + * @covers \MensBeam\HTML\DOM\Element::setAttribute + * @covers \MensBeam\HTML\DOM\HTMLCollection::item + * @covers \MensBeam\HTML\DOM\HTMLCollection::offsetGet + * @covers \MensBeam\HTML\DOM\Node::__construct + * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument + * @covers \MensBeam\HTML\DOM\Node::getInnerDocument + * @covers \MensBeam\HTML\DOM\Node::hasChildNodes + * @covers \MensBeam\HTML\DOM\Node::postParsingTemplatesFix + * @covers \MensBeam\HTML\DOM\Inner\Document::__construct + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_wrapperNode + * @covers \MensBeam\HTML\DOM\Inner\Document::__get_xpath + * @covers \MensBeam\HTML\DOM\Inner\Document::getWrapperNode + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::get + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::has + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::key + * @covers \MensBeam\HTML\DOM\Inner\NodeCache::set + * @covers \MensBeam\HTML\DOM\Inner\Reflection::createFromProtectedConstructor + */ + public function testProperty_translate(): void { + $d = new Document('
Ook
'); + $html = $d->documentElement; + $span = $d->getElementsByTagName('span')[0]; + + $this->assertFalse($span->translate); + $span->translate = true; + $this->assertTrue($span->translate); + $span->removeAttribute('translate'); + $html->translate = true; + $this->assertTrue($span->translate); + $span->translate = false; + $this->assertFalse($span->translate); + } } \ No newline at end of file diff --git a/tests/cases/TestHTMLOrSVGElement.php b/tests/cases/TestHTMLOrSVGElement.php new file mode 100644 index 0000000..a957abb --- /dev/null +++ b/tests/cases/TestHTMLOrSVGElement.php @@ -0,0 +1,29 @@ +'); + $html = $d->documentElement; + $this->assertFalse($html->autofocus); + $html->autofocus = true; + $this->assertTrue($html->autofocus); + $html->autofocus = false; + $this->assertFalse($html->autofocus); + $this->assertFalse($html->hasAttribute('autofocus')); + } +} \ No newline at end of file diff --git a/tests/phpunit.dist.xml b/tests/phpunit.dist.xml index 8f05381..f1e5d16 100644 --- a/tests/phpunit.dist.xml +++ b/tests/phpunit.dist.xml @@ -27,6 +27,7 @@ cases/TestElement.php cases/TestHTMLCollection.php cases/TestHTMLElement.php + cases/TestHTMLOrSVGElement.php cases/TestInnerDocument.php cases/TestNamedNodeMap.php cases/TestNode.php diff --git a/vendor-bin/phpunit/composer.lock b/vendor-bin/phpunit/composer.lock index 6c1b242..460b4b2 100644 --- a/vendor-bin/phpunit/composer.lock +++ b/vendor-bin/phpunit/composer.lock @@ -92,6 +92,9 @@ "require": { "php": "^7.1 || ^8.0" }, + "replace": { + "myclabs/deep-copy": "self.version" + }, "require-dev": { "doctrine/collections": "^1.0", "doctrine/common": "^2.6", @@ -844,16 +847,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.10", + "version": "9.5.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a" + "reference": "2406855036db1102126125537adb1406f7242fdd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a", - "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2406855036db1102126125537adb1406f7242fdd", + "reference": "2406855036db1102126125537adb1406f7242fdd", "shasum": "" }, "require": { @@ -931,11 +934,11 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.11" }, "funding": [ { - "url": "https://phpunit.de/donate.html", + "url": "https://phpunit.de/sponsors.html", "type": "custom" }, { @@ -943,7 +946,7 @@ "type": "github" } ], - "time": "2021-09-25T07:38:51+00:00" + "time": "2021-12-25T07:07:57+00:00" }, { "name": "sebastian/cli-parser", @@ -2105,5 +2108,5 @@ "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.1.0" } diff --git a/vendor-bin/robo/composer.lock b/vendor-bin/robo/composer.lock index 54e1257..f959b65 100644 --- a/vendor-bin/robo/composer.lock +++ b/vendor-bin/robo/composer.lock @@ -8,27 +8,28 @@ "packages": [ { "name": "consolidation/annotated-command", - "version": "4.4.0", + "version": "4.5.0", "source": { "type": "git", "url": "https://github.com/consolidation/annotated-command.git", - "reference": "308f6ac178566a1ce9aa90ed908dac90a2c1e707" + "reference": "df01c1f1449c6b46bf87051e0b418bd5d5e44a7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/308f6ac178566a1ce9aa90ed908dac90a2c1e707", - "reference": "308f6ac178566a1ce9aa90ed908dac90a2c1e707", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/df01c1f1449c6b46bf87051e0b418bd5d5e44a7a", + "reference": "df01c1f1449c6b46bf87051e0b418bd5d5e44a7a", "shasum": "" }, "require": { "consolidation/output-formatters": "^4.1.1", "php": ">=7.1.3", "psr/log": "^1|^2", - "symfony/console": "^4.4.8|~5.1.0", - "symfony/event-dispatcher": "^4.4.8|^5", - "symfony/finder": "^4.4.8|^5" + "symfony/console": "^4.4.8|^5|^6", + "symfony/event-dispatcher": "^4.4.8|^5|^6", + "symfony/finder": "^4.4.8|^5|^6" }, "require-dev": { + "composer-runtime-api": "^2.0", "phpunit/phpunit": "^7.5.20 || ^8 || ^9", "squizlabs/php_codesniffer": "^3", "yoast/phpunit-polyfills": "^0.2.0" @@ -57,9 +58,9 @@ "description": "Initialize Symfony Console commands from annotated command class methods.", "support": { "issues": "https://github.com/consolidation/annotated-command/issues", - "source": "https://github.com/consolidation/annotated-command/tree/4.4.0" + "source": "https://github.com/consolidation/annotated-command/tree/4.5.0" }, - "time": "2021-09-30T01:08:15+00:00" + "time": "2021-12-27T19:34:17+00:00" }, { "name": "consolidation/config", @@ -175,30 +176,30 @@ }, { "name": "consolidation/output-formatters", - "version": "4.1.2", + "version": "4.2.0", "source": { "type": "git", "url": "https://github.com/consolidation/output-formatters.git", - "reference": "5821e6ae076bf690058a4de6c94dce97398a69c9" + "reference": "27cf221f6e59b1debed0c6c94015e78cd5f10e24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/5821e6ae076bf690058a4de6c94dce97398a69c9", - "reference": "5821e6ae076bf690058a4de6c94dce97398a69c9", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/27cf221f6e59b1debed0c6c94015e78cd5f10e24", + "reference": "27cf221f6e59b1debed0c6c94015e78cd5f10e24", "shasum": "" }, "require": { "dflydev/dot-access-data": "^1.1.0", "php": ">=7.1.3", - "symfony/console": "^4|^5", - "symfony/finder": "^4|^5" + "symfony/console": "^4|^5|^6", + "symfony/finder": "^4|^5|^6" }, "require-dev": { "php-coveralls/php-coveralls": "^2.4.2", "phpunit/phpunit": ">=7", "squizlabs/php_codesniffer": "^3", - "symfony/var-dumper": "^4", - "symfony/yaml": "^4", + "symfony/var-dumper": "^4|^5|^6", + "symfony/yaml": "^4|^5|^6", "yoast/phpunit-polyfills": "^0.2.0" }, "suggest": { @@ -228,9 +229,9 @@ "description": "Format text by applying transformations provided by plug-in formatters.", "support": { "issues": "https://github.com/consolidation/output-formatters/issues", - "source": "https://github.com/consolidation/output-formatters/tree/4.1.2" + "source": "https://github.com/consolidation/output-formatters/tree/4.2.0" }, - "time": "2020-12-12T19:04:59+00:00" + "time": "2021-12-27T14:30:41+00:00" }, { "name": "consolidation/robo", @@ -764,27 +765,29 @@ }, { "name": "symfony/console", - "version": "v5.1.11", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d9a267b621c5082e0a6c659d73633b6fd28a8a08" + "reference": "a2c6b7ced2eb7799a35375fb9022519282b5405e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d9a267b621c5082e0a6c659d73633b6fd28a8a08", - "reference": "d9a267b621c5082e0a6c659d73633b6fd28a8a08", + "url": "https://api.github.com/repos/symfony/console/zipball/a2c6b7ced2eb7799a35375fb9022519282b5405e", + "reference": "a2c6b7ced2eb7799a35375fb9022519282b5405e", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.15", - "symfony/service-contracts": "^1.1|^2", - "symfony/string": "^5.1" + "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.1|^6.0" }, "conflict": { + "psr/log": ">=3", "symfony/dependency-injection": "<4.4", "symfony/dotenv": "<5.1", "symfony/event-dispatcher": "<4.4", @@ -792,16 +795,16 @@ "symfony/process": "<4.4" }, "provide": { - "psr/log-implementation": "1.0" + "psr/log-implementation": "1.0|2.0" }, "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/event-dispatcher": "^4.4|^5.0", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", - "symfony/var-dumper": "^4.4|^5.0" + "psr/log": "^1|^2", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/event-dispatcher": "^4.4|^5.0|^6.0", + "symfony/lock": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/var-dumper": "^4.4|^5.0|^6.0" }, "suggest": { "psr/log": "For using the console logger", @@ -834,8 +837,14 @@ ], "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command line", + "console", + "terminal" + ], "support": { - "source": "https://github.com/symfony/console/tree/v5.1.11" + "source": "https://github.com/symfony/console/tree/v5.4.2" }, "funding": [ { @@ -851,29 +860,29 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:01:46+00:00" + "time": "2021-12-20T16:11:12+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" + "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", + "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -902,7 +911,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.0" }, "funding": [ { @@ -918,7 +927,7 @@ "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2021-11-01T23:48:49+00:00" }, { "name": "symfony/event-dispatcher", @@ -1150,16 +1159,16 @@ }, { "name": "symfony/finder", - "version": "v5.4.0", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "d2f29dac98e96a98be467627bd49c2efb1bc2590" + "reference": "e77046c252be48c48a40816187ed527703c8f76c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/d2f29dac98e96a98be467627bd49c2efb1bc2590", - "reference": "d2f29dac98e96a98be467627bd49c2efb1bc2590", + "url": "https://api.github.com/repos/symfony/finder/zipball/e77046c252be48c48a40816187ed527703c8f76c", + "reference": "e77046c252be48c48a40816187ed527703c8f76c", "shasum": "" }, "require": { @@ -1193,7 +1202,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.0" + "source": "https://github.com/symfony/finder/tree/v5.4.2" }, "funding": [ { @@ -1209,7 +1218,7 @@ "type": "tidelift" } ], - "time": "2021-11-28T15:25:38+00:00" + "time": "2021-12-15T11:06:13+00:00" }, { "name": "symfony/polyfill-ctype", @@ -1699,16 +1708,16 @@ }, { "name": "symfony/process", - "version": "v5.4.0", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "5be20b3830f726e019162b26223110c8f47cf274" + "reference": "2b3ba8722c4aaf3e88011be5e7f48710088fb5e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/5be20b3830f726e019162b26223110c8f47cf274", - "reference": "5be20b3830f726e019162b26223110c8f47cf274", + "url": "https://api.github.com/repos/symfony/process/zipball/2b3ba8722c4aaf3e88011be5e7f48710088fb5e4", + "reference": "2b3ba8722c4aaf3e88011be5e7f48710088fb5e4", "shasum": "" }, "require": { @@ -1741,7 +1750,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.0" + "source": "https://github.com/symfony/process/tree/v5.4.2" }, "funding": [ { @@ -1757,26 +1766,25 @@ "type": "tidelift" } ], - "time": "2021-11-28T15:25:38+00:00" + "time": "2021-12-27T21:01:00+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.5.0", + "version": "v2.4.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" + "reference": "d664541b99d6fb0247ec5ff32e87238582236204" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d664541b99d6fb0247ec5ff32e87238582236204", + "reference": "d664541b99d6fb0247ec5ff32e87238582236204", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1" + "psr/container": "^1.1" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -1787,7 +1795,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -1824,7 +1832,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v2.4.1" }, "funding": [ { @@ -1840,38 +1848,37 @@ "type": "tidelift" } ], - "time": "2021-11-04T16:48:04+00:00" + "time": "2021-11-04T16:37:19+00:00" }, { "name": "symfony/string", - "version": "v5.4.0", + "version": "v6.0.2", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d" + "reference": "bae261d0c3ac38a1f802b4dfed42094296100631" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d", - "reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d", + "url": "https://api.github.com/repos/symfony/string/zipball/bae261d0c3ac38a1f802b4dfed42094296100631", + "reference": "bae261d0c3ac38a1f802b4dfed42094296100631", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "~1.15" + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/translation-contracts": ">=3.0" + "symfony/translation-contracts": "<2.0" }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/http-client": "^4.4|^5.0|^6.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0|^6.0" + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" }, "type": "library", "autoload": { @@ -1910,7 +1917,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.0" + "source": "https://github.com/symfony/string/tree/v6.0.2" }, "funding": [ { @@ -1926,32 +1933,32 @@ "type": "tidelift" } ], - "time": "2021-11-24T10:02:00+00:00" + "time": "2021-12-16T22:13:01+00:00" }, { "name": "symfony/yaml", - "version": "v5.3.11", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "226638aa877bc4104e619a15f27d8141cd6b4e4a" + "reference": "b9eb163846a61bb32dfc147f7859e274fab38b58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/226638aa877bc4104e619a15f27d8141cd6b4e4a", - "reference": "226638aa877bc4104e619a15f27d8141cd6b4e4a", + "url": "https://api.github.com/repos/symfony/yaml/zipball/b9eb163846a61bb32dfc147f7859e274fab38b58", + "reference": "b9eb163846a61bb32dfc147f7859e274fab38b58", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-ctype": "~1.8" + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<4.4" + "symfony/console": "<5.3" }, "require-dev": { - "symfony/console": "^4.4|^5.0" + "symfony/console": "^5.3|^6.0" }, "suggest": { "symfony/console": "For validating YAML files using the lint command" @@ -1985,7 +1992,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.3.11" + "source": "https://github.com/symfony/yaml/tree/v5.4.2" }, "funding": [ { @@ -2001,7 +2008,7 @@ "type": "tidelift" } ], - "time": "2021-11-20T16:42:42+00:00" + "time": "2021-12-16T21:58:21+00:00" } ], "packages-dev": [], @@ -2012,5 +2019,5 @@ "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.1.0" }