rfc:dom_living_standard_api

This is an old revision of the document!


PHP RFC: Implement Current DOM Living Standard API

Introduction

Working with XML (HTML) documents is a necessary task for many web applications and the dom extension implements a standardized API that was previously specified by a w3 group into 3 DOM Levels. Since then the standard has evolved and is now a Living Standard similar to HTML 5 and continously evolving and maintained by the Web Hypertext Application Technology Working Group (WHATWG).

- https://dom.spec.whatwg.org

Because the new API provides much improved traversal and manipulation APIs than the old API we propose to add the new methods to the existing ext/dom API.

Specifically we think this is a better solution to providing them in userland, because

  1. ext/dom + DOMDocument represents the DOM Standard, so we should continue to support the evolving versions.
  2. the added methods are a huge value add to users and fix a lot of more complicated approaches that were previously required by users. The search or re-implementation costs are high for users.

Proposal

Follow the DOM Living Standard with ext/dom

This RFC proposes to adapt the current DOM standard changes to the PHP langauge by introducing new interfaces and public properties that simplify traversal and manipulation of DOM elements.

<?php
interface DOMParentNode
{
    public readonly DOMNode? $previousElementNode;
    public readonly DOMNode? $nextElementNode;
    public readonly int $childElementCount;
 
    public function append(...DOMNode|string|null $nodes) : void;
    public function prepend(...DOMNode|string|null $nodes) : void;
}
 
class DOMDocument implements DOMParentNode {}
class DOMElement implements DOMParentNode {}
class DOMDocumentFragment implements DOMParentNode {}
 
interface DOMChildNode
{
    public readonly DOMNode? $previousElementSibling;
    public readonly DOMNode? $nextElementSibling;
 
    public function remove() : void;
    public function before(...DOMNode|string|null $nodes) : void;
    public function after(...DOMNode|string|null $nodes) : void;
    public function replaceWith(...DOMNode|string|null $nodes) : void;
}
 
class DOMElement implements DOMChildNode {}
class DOMCharacterData implements DOMChildNode {}
class DOMDocumentType implements DOMChildNode {}

Implementation choices:

The standard implements these interfaces as “traits” and doesn't provide interfaces for them. This might make more sense with the primary language target (JavaScript), but for PHP it makes more sense to have the functionality available through an interface.

The standard contains an intermediate interface DOMNonDocumentTypeChildNode that contains the previousElementSibling and nextElementSibling properties. This is introduced to provide backwards compatibility with browser/web implementations, which are not our concern. In addition PHP interfaces cannot have properties, so it wouldn't make sense to add this empty interface. For this reason this class was not introduced, but the properties are instead on DOMChildNode directly.

The querySelector and querySelectorAll methods defined on the DOMParentNode interface are omitted, because of their underlying complexity (using a CSS query selector parser) we recommend to leave implementations of comparable functionality to userland libraries such as PhpCss or Symfony CSS Selector.

Backward Incompatible Changes

Code using registerNodeClass to overwrite DOM classes can be affected IF they already implement the new functionality in a way that doesn't satisfy the behavior or signature of this proposed code changes.

Proposed PHP Version(s)

PHP 8.0

RFC Impact

To SAPIs

No effect on SAPIs.

To Existing Extensions

The dom extensions API is changed in a mostly backwards compatible way (only adding new properties/methods). Breaking is code using registerNodeClass that adds child classes that also implement the new methods, but use a different signature.

The new functionality can all be implemented entirely using the already available libxml2 datastructures, so no changes to the libxml2 dependency is nceessary.

To Opcache

No effect on Opcache.

Patches and Tests

https://github.com/beberlei/php-src/pull/1

This pull request is still work in progress.

Implementation

tbd

References

- DOM Living Standard Document https://dom.spec.whatwg.org

rfc/dom_living_standard_api.1568567957.txt.gz · Last modified: 2019/09/15 17:19 by beberlei