1 /*
2 *             Copyright László Szerémi 2022 - .
3 *  Distributed under the Boost Software License, Version 1.0.
4 *      (See accompanying file LICENSE_1_0.txt or copy at
5 *            http://www.boost.org/LICENSE_1_0.txt)
6 */
7 
8 /++
9 +   This module declares the DOM Level 3 interfaces as stated in the W3C DOM
10 +   specification.
11 +
12 +   For a more complete reference, see the
13 +   $(LINK2 https://www.w3.org/TR/DOM-Level-3-Core/, official specification),
14 +   from which all documentation in this module is taken.
15 +
16 +   Authors:
17 +   Lodovico Giaretta
18 +   László Szerémi
19 +
20 +   License:
21 +   <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
22 +
23 +   Copyright:
24 +   Copyright Lodovico Giaretta 2016 --
25 +/
26 
27 module newxml.dom;
28 
29 import newxml.interfaces;
30 public import newxml.domstring;
31 import std.typecons : BitFlags;
32 import std.variant : Variant;
33 
34 /++
35 +   The DOMUserData type is used to store application data inside DOM nodes.
36 +/
37 alias UserData = Variant;
38 
39 /++
40 +   When associating an object to a key on a node using Node.setUserData() the
41 +   application can provide a handler that gets called when the node the object
42 +   is associated to is being cloned, imported, or renamed. This can be used by
43 +   the application to implement various behaviors regarding the data it associates
44 +   to the DOM nodes.
45 +/
46 alias UserDataHandler = void delegate(UserDataOperation, DOMString, UserData, Node, Node) @safe;
47 
48 /++
49 +   An integer indicating which type of node this is.
50 +
51 +   Note:
52 +   Numeric codes up to 200 are reserved to W3C for possible future use.
53 +/
54 enum NodeType: ushort
55 {
56     element = 1,
57     attribute,
58     text,
59     cdataSection,
60     entityReference,
61     entity,
62     processingInstruction,
63     comment,
64     document,
65     documentType,
66     documentFragment,
67     notation,
68 }
69 
70 /++
71 +   A bitmask indicating the relative document position of a node with respect to another node.
72 +   Returned by `Node.compareDocumentPosition`.
73 +/
74 enum DocumentPosition: ushort
75 {
76     /// Set when the two nodes are in fact the same
77     none         = 0,
78     /// Set when the two nodes are not in the same tree
79     disconnected = 1,
80     /// Set when the second node precedes the first
81     preceding    = 2,
82     /// Set when the second node follows the first
83     following    = 4,
84     /// Set when the second node _contains the first
85     contains     = 8,
86     /// Set when the second node is contained by the first
87     containedBy = 16,
88     /++
89     +   Set when the returned ordering of the two nodes may be different across
90     +   DOM implementations; for example, for two attributes of the same node,
91     +   an implementation may return `preceding | implementationSpecific` and another
92     +   may return `following | implementationSpecific`, because at the DOM level
93     +   the attributes ordering is unspecified
94     +/
95     implementationSpecific = 32,
96 }
97 
98 /++
99 +   An integer indicating the type of operation being performed on a node.
100 +/
101 enum UserDataOperation: ushort
102 {
103     /// The node is cloned, using `Node.cloneNode()`.
104     nodeCloned = 1,
105     /// The node is imported, using `Document.importNode()`.
106     nodeImported,
107     /++
108     +   The node is deleted.
109     +
110     +   Note:
111     +   This may not be supported or may not be reliable in certain environments,
112     +   where the implementation has no real control over when objects are actually deleted.
113     +/
114     nodeDeleted,
115     /// The node is renamed, using `Document.renameNode()`.
116     nodeRenamed,
117     /// The node is adopted, using `Document.adoptNode()`.
118     nodeAdopted,
119 }
120 
121 /++
122 +   An integer indicating the type of error generated.
123 +
124 +   Note:
125 +   Other numeric codes are reserved for W3C for possible future use.
126 +/
127 enum ExceptionCode: ushort
128 {
129     /// If index or size is negative, or greater than the allowed value.
130     indexSize,
131     /// If the specified range of text does not fit into a `DOMString`.
132     domStringSize,
133     /// If any `Node` is inserted somewhere it doesn't belong.
134     hierarchyRequest,
135     /// If a `Node` is used in a different document than the one that created it (that doesn't support it).
136     wrongDocument,
137     /// If an invalid or illegal character is specified, such as in an XML name.
138     invalidCharacter,
139     /// If data is specified for a `Node` which does not support data.
140     noDataAllowed,
141     /// If an attempt is made to modify an object where modifications are not allowed.
142     noModificationAllowed,
143     /// If an attempt is made to reference a `Node` in a context where it does not exist.
144     notFound,
145     /// If the implementation does not support the requested type of object or operation.
146     notSupported,
147     /// If an attempt is made to add an attribute that is already in use elsewhere.
148     inuseAttribute,
149     /// If an attempt is made to use an object that is not, or is no longer, usable.
150     invalidState,
151     /// If an invalid or illegal string is specified.
152     syntax,
153     /// If an attempt is made to modify the type of the underlying object.
154     invalidModification,
155     /// If an attempt is made to create or change an object in a way which is incorrect with regard to namespaces.
156     namespace,
157     /// If a parameter or an operation is not supported by the underlying object.
158     invalidAccess,
159     /// If a call to a method such as insertBefore or removeChild would make the `Node` invalid.
160     validation,
161     /// If the type of an object is incompatible with the expected type of the parameter associated to the object.
162     typeMismatch,
163 }
164 
165 /// An integer indicating the severity of a `DOMError`.
166 enum ErrorSeverity: ushort
167 {
168     /++
169     +   The severity of the error described by the `DOMError` is warning. A `WARNING`
170     +   will not cause the processing to stop, unless the call of the `DOMErrorHandler`
171     +   returns `false`.
172     +/
173     warning,
174     /++
175     +   The severity of the error described by the `DOMError` is error. A `ERROR`
176     +   may not cause the processing to stop if the error can be recovered, unless
177     +   the call of the `DOMErrorHandler` returns `false`.
178     +/
179     error,
180     /++
181     +   The severity of the error described by the `DOMError` is fatal error. A `FATAL_ERROR`
182     +   will cause the normal processing to stop. The return value of calling the `DOMErrorHandler`
183     +   is ignored unless the implementation chooses to continue, in which case
184     +   the behavior becomes undefined.
185     +/
186     fatalError,
187 }
188 
189 enum DerivationMethod: ulong
190 {
191     restriction = 0x00000001,
192     extension   = 0x00000002,
193     union_      = 0x00000004,
194     list        = 0x00000008,
195 }
196 @safe:
197 /++
198 +   DOM operations only raise exceptions in "exceptional" circumstances, i.e.,
199 +   when an operation is impossible to perform (either for logical reasons, because
200 +   data is lost, or because the implementation has become unstable). In general,
201 +   DOM methods return specific error values in ordinary processing situations,
202 +   such as out-of-bound errors when using `NodeList`.
203 +
204 +   Implementations should raise other exceptions under other circumstances. For
205 +   example, implementations should raise an implementation-dependent exception
206 +   if a `null` argument is passed when `null` was not expected.
207 +/
208 abstract class DOMException: XMLException
209 {
210     ///
211     @property ExceptionCode code();
212 
213     ///
214     @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, 
215             Throwable nextInChain = null)
216     {
217         super(msg, file, line, nextInChain);
218     }
219 
220     @nogc @safe pure nothrow this(string msg, Throwable nextInChain, string file = __FILE__, size_t line = __LINE__)
221     {
222         super(msg, file, line, nextInChain);
223     }
224 }
225 
226 /++
227 +   The `DOMStringList` interface provides the abstraction of an ordered collection
228 +   of `DOMString` values, without defining or constraining how this collection is
229 +   implemented. The items in the DOMStringList are accessible via an integral index,
230 +   starting from `0`.
231 +/
232 interface DOMStringList {
233     DOMString item(size_t index);
234     @property size_t length();
235     bool contains(DOMString str);
236 };
237 
238 /++
239 +   The `DOMImplementationList` interface provides the abstraction of an ordered
240 +   collection of DOM implementations, without defining or constraining how this
241 +   collection is implemented. The items in the `DOMImplementationList` are accessible
242 +   via an integral index, starting from `0`.
243 +/
244 interface DOMImplementationList {
245     DOMImplementation item(size_t index);
246     @property size_t length();
247 }
248 
249 /++
250 +   This interface permits a DOM implementer to supply one or more implementations,
251 +   based upon requested features and versions, as specified in DOM Features.
252 +   Each implemented DOMImplementationSource object is listed in the binding-specific
253 +   list of available sources so that its `DOMImplementation` objects are made available.
254 +/
255 interface DOMImplementationSource {
256     /// A method to request the first DOM implementation that supports the specified features.
257     DOMImplementation getDOMImplementation(DOMString features);
258     /// A method to request a list of DOM implementations that support the specified features and versions, as specified in DOM Features.
259     DOMImplementationList getDOMImplementationList(DOMString features);
260 }
261 
262 /++
263 +   The DOMImplementation interface provides a number of methods for performing
264 +   operations that are independent of any particular instance of the document object model.
265 +/
266 interface DOMImplementation {
267     /++
268     +   Creates an empty DocumentType node. Entity declarations and notations are not
269     +   made available. Entity reference expansions and default attribute additions do not occur.
270     +/
271     DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId, DOMString systemId);
272 
273     /++
274     +   Creates a DOM Document object of the specified type with its document element.
275     +
276     +   Note that based on the DocumentType given to create the document, the implementation
277     +   may instantiate specialized Document objects that support additional features than the "Core",
278     +   such as "HTML". On the other hand, setting the DocumentType after the document
279     +   was created makes this very unlikely to happen.
280     +/
281     Document createDocument(DOMString namespaceURI, DOMString qualifiedName, DocumentType doctype);
282 
283     bool hasFeature(string feature, string version_);
284     Object getFeature(string feature, string version_);
285 }
286 
287 /++
288 +   `DocumentFragment` is a "lightweight" or "minimal" `Document` object. It is very
289 +   common to want to be able to extract a portion of a document's tree or to create
290 +   a new fragment of a document. Imagine implementing a user command like cut or
291 +   rearranging a document by moving fragments around. It is desirable to have an
292 +   object which can hold such fragments and it is quite natural to use a `Node`
293 +   for this purpose. While it is true that a `Document` object could fulfill this
294 +   role, a `Document` object can potentially be a heavyweight object, depending
295 +   on the underlying implementation. What is really needed for this is a very lightweight
296 +   object. `DocumentFragment` is such an object.
297 +
298 +   Furthermore, various operations -- such as inserting nodes as children of another
299 +   `Node` -- may take `DocumentFragment` objects as arguments; this results in
300 +   all the child nodes of the `DocumentFragment` being moved to the child list of this node.
301 +
302 +   The children of a `DocumentFragment` node are zero or more nodes representing
303 +   the tops of any sub-trees defining the structure of the document. `DocumentFragment`
304 +   nodes do not need to be well-formed XML documents (although they do need to follow
305 +   the rules imposed upon well-formed XML parsed entities, which can have multiple
306 +   top nodes). For example, a `DocumentFragment` might have only one child and that
307 +   child node could be a `Text` node. Such a structure model represents neither
308 +   an HTML document nor a well-formed XML document.
309 +
310 +   When a `DocumentFragment` is inserted into a `Document` (or indeed any other
311 +   `Node` that may take children) the children of the `DocumentFragment` and not
312 +   the `DocumentFragment` itself are inserted into the `Node`. This makes the `DocumentFragment`
313 +   very useful when the user wishes to create nodes that are siblings; the `DocumentFragment`
314 +   acts as the parent of these nodes so that the user can use the standard methods
315 +   from the `Node` interface, such as `Node.insertBefore` and `Node.appendChild`.
316 +/
317 interface DocumentFragment : Node {
318 }
319 
320 /++
321 +   The `Document` interface represents the entire HTML or XML document. Conceptually,
322 +   it is the root of the document tree, and provides the primary access to the document's data.
323 +
324 +   Since elements, text nodes, comments, processing instructions, etc. cannot exist
325 +   outside the context of a `Document`, the `Document` interface also contains the
326 +   factory methods needed to create these objects. The `Node` objects created have
327 +   a `ownerDocument` attribute which associates them with the `Document` within
328 +   whose context they were created.
329 +/
330 interface Document : Node {
331     /++
332     +   The `DocumentType` associated with this document. For XML documents without a
333     +   document type declaration this returns `null`.
334     +
335     +   This provides direct access to the `DocumentType` node, child node of this
336     +   `Document`. This node can be set at document creation time and later changed
337     +   through the use of child nodes manipulation methods, such as `Node.insertBefore`,
338     +   or `Node.replaceChild`.
339     +/
340     @property DocumentType doctype();
341     /++
342     +   The `DOMImplementation` object that handles this document. A DOM application
343     +   may use objects from multiple implementations.
344     +/
345     @property DOMImplementation implementation();
346     /++
347     +   This is a convenience attribute that allows direct access to the child node
348     +   that is the document element of the document.
349     +/
350     @property Element documentElement();
351 
352     /++
353     +   Creates an `Element` of the type specified.
354     +   In addition, if there are known attributes with default values, `Attr` nodes
355     +   representing them are automatically created and attached to the element.
356     +   To create an `Element` with a qualified name and namespace URI, use the
357     +   `createElementNS` method.
358     +/
359     Element createElement(DOMString tagName);
360     /++
361     +   Creates an `Element` of the given qualified name and namespace URI.
362     +   Per the XML Namespaces specification, applications must use the value `null`
363     +   as the `namespaceURI` parameter for methods if they wish to have no namespace.
364     +/
365     Element createElementNS(DOMString namespaceURI, DOMString qualifiedName);
366     /// Creates an empty `DocumentFragment` object.
367     DocumentFragment createDocumentFragment();
368     /// Creates a `Text` node given the specified string.
369     Text createTextNode(DOMString data);
370     /// Creates a `Comment` node given the specified string.
371     Comment createComment(DOMString data);
372     /// Creates a `CDATASection` node whose value is the specified string.
373     CDATASection createCDATASection(DOMString data);
374     /// Creates a `ProcessingInstruction` node given the specified name and data strings.
375     ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
376     /++
377     +   Creates an `Attr` of the given name. Note that the `Attr` instance can
378     +   then be set on an `Element` using the `setAttributeNode` method.
379     +   To create an attribute with a qualified name and namespace URI, use the
380     +   `createAttributeNS` method.
381     +/
382     Attr createAttribute(DOMString name);
383     /++
384     +   Creates an attribute of the given qualified name and namespace URI.
385     +   Per the XML Namespaces specification, applications must use the value `null`
386     +   as the `namespaceURI` parameter for methods if they wish to have no namespace.
387     +/
388     Attr createAttributeNS(DOMString namespaceURI, DOMString qualifiedName);
389     /++
390     +   Creates an `EntityReference` object. In addition, if the referenced entity
391     +   is known, the child list of the `EntityReference` node is made the same as
392     +   that of the corresponding `Entity` node.
393     +/
394     EntityReference createEntityReference(DOMString name);
395 
396     /++
397     +   Returns a `NodeList` of all the `Element`s in document order with a given
398     +   tag name and are contained in the document.
399     +/
400     NodeList getElementsByTagName(DOMString tagname);
401     /++
402     +   Returns a `NodeList` of all the `Element`s with a given local name and
403     +   namespace URI in document order.
404     +/
405     NodeList getElementsByTagNameNS(DOMString namespaceURI, DOMString localName);
406     /++
407     +   Returns the `Element` that has an ID attribute with the given value. If no
408     +   such element exists, this returns `null`. If more than one element has an
409     +   ID attribute with that value, what is returned is undefined.
410     +   The DOM implementation is expected to use the attribute `Attr.isId` to
411     +   determine if an attribute is of type ID.
412     +
413     +   Note: Attributes with the name "ID" or "id" are not of type ID unless so defined.
414     +/
415     Element getElementById(DOMString elementId);
416 
417     /++
418     +   Imports a node from another document to this document, without altering or
419     +   removing the source node from the original document; this method creates a
420     +   new copy of the source node. The returned node has no parent; (`parentNode` is `null`).
421     +
422     +   For all nodes, importing a node creates a node object owned by the importing
423     +   document, with attribute values identical to the source node's `nodeName` and
424     +   `nodeType`, plus the attributes related to namespaces (`prefix`, `localName`,
425     +   and `namespaceURI`). As in the `cloneNode` operation, the source node is
426     +   not altered. User data associated to the imported node is not carried over.
427     +   However, if any `UserData` handlers has been specified along with the associated
428     +   data these handlers will be called with the appropriate parameters before this
429     +   method returns.
430     +/
431     Node importNode(Node importedNode, bool deep);
432     /++
433     +   Moves node from another document, and returns it. Throws "NotSupportedError" DOMException if node is a 
434     +   document, or a "HierarchyRequestError" DOMException if node is a shadow root.
435     +/
436     Node adoptNode(Node source);
437 
438     /++
439     +   An attribute specifying the encoding used for this document at the time of
440     +   the parsing. This is `null` when it is not known, such as when the `Document`
441     +   was created in memory.
442     +/
443     @property DOMString inputEncoding();
444     /++
445     +   An attribute specifying, as part of the XML declaration, the encoding of
446     +   this document. This is `null` when unspecified or when it is not known,
447     +   such as when the Document was created in memory.
448     +/
449     @property DOMString xmlEncoding();
450 
451     /++
452     +   An attribute specifying, as part of the XML declaration, whether this document
453     +   is standalone. This is `false` when unspecified.
454     +/
455     @property bool xmlStandalone();
456     /// ditto
457     @property void xmlStandalone(bool);
458 
459     /++
460     +   An attribute specifying, as part of the XML declaration, the version number
461     +   of this document. If there is no declaration and if this document supports
462     +   the "XML" feature, the value is "1.0". If this document does not support
463     +   the "XML" feature, the value is always `null`.
464     +/
465     @property DOMString xmlVersion();
466     /// ditto
467     @property void xmlVersion(DOMString);
468 
469     /++
470     +   An attribute specifying whether error checking is enforced or not.
471     +   When set to `false`, the implementation is free to not test every possible
472     +   error case normally defined on DOM operations, and not raise any `DOMException`
473     +   on DOM operations or report errors while using `Document.normalizeDocument()`.
474     +   In case of error, the behavior is undefined. This attribute is `true` by default.
475     +/
476     @property bool strictErrorChecking();
477     /// ditto
478     @property void strictErrorChecking(bool);
479 
480     /++
481     +   The location of the document or `null` if undefined or if the `Document`
482     +   was created using `DOMImplementation.createDocument`. No lexical checking
483     +   is performed when setting this attribute; this could result in a `null`
484     +   value returned when using `Node.baseURI`.
485     +/
486     @property DOMString documentURI();
487     /// ditto
488     @property void documentURI(DOMString);
489 
490     /// The configuration used when `Document.normalizeDocument()` is invoked.
491     @property DOMConfiguration domConfig();
492     /++
493     +   This method acts as if the document was going through a save and load cycle,
494     +   putting the document in a "normal" form. As a consequence, this method
495     +   updates the replacement tree of `EntityReference` nodes and normalizes `Text`
496     +   nodes, as defined in the method Node.normalize().
497     +/
498     void normalizeDocument();
499     /++
500     +   Rename an existing node of type `ELEMENT` or `ATTRIBUTE`.
501     +
502     +   When possible this simply changes the name of the given node, otherwise
503     +   this creates a new node with the specified name and replaces the existing
504     +   node with the new node as described below.
505     +   If simply changing the name of the given node is not possible, the following
506     +   operations are performed: a new node is created, any registered event
507     +   listener is registered on the new node, any user data attached to the old
508     +   node is removed from that node, the old node is removed from its parent
509     +   if it has one, the children are moved to the new node, if the renamed node
510     +   is an `Element` its attributes are moved to the new node, the new node is
511     +   inserted at the position the old node used to have in its parent's child
512     +   nodes list if it has one, the user data that was attached to the old node
513     +   is attached to the new node.
514     +/
515     Node renameNode(Node n, DOMString namespaceURI, DOMString qualifiedName);
516 }
517 
518 /++
519 +   The `Node` interface is the primary datatype for the entire Document Object Model.
520 +   It represents a single node in the document tree. While all objects implementing
521 +   the `Node` interface expose methods for dealing with children, not all objects
522 +   implementing the `Node` interface may have children. For example, `Text` nodes
523 +   may not have children, and adding children to such nodes results in a `DOMException`
524 +   being raised.
525 +
526 +   The attributes `nodeName`, `nodeValue` and `attributes` are included as a mechanism
527 +   to get at node information without casting down to the specific derived interface.
528 +   In cases where there is no obvious mapping of these attributes for a specific `nodeType`
529 +   (e.g., `nodeValue` for an `Element` or attributes for a `Comment`), this returns `null`.
530 +   Note that the specialized interfaces may contain additional and more convenient
531 +   mechanisms to get and set the relevant information.
532 +/
533 interface Node {
534     /// A code representing the type of the underlying object.
535     @property NodeType nodeType();
536     /// The name of this node, depending on its type.
537     @property DOMString nodeName();
538     /++
539     +   Returns the local part of the qualified name of this node.
540     +
541     +   For nodes of any type other than `ELEMENT` and `ATTRIBUTE` and nodes created
542     +   with a DOM Level 1 method, such as `Document.createElement`, this is always `null`.
543     +/
544     @property DOMString localName();
545     /++
546     +   The namespace prefix of this node, or `null` if it is unspecified.
547     +   When it is defined to be `null`, setting it has no effect, including if
548     +   the node is read-only.
549     +   Note that setting this attribute, when permitted, changes the `nodeName`
550     +   attribute, which holds the qualified name, as well as the `tagName` and
551     +   `name` attributes of the `Element` and `Attr` interfaces, when applicable.
552     +   Setting the prefix to `null` makes it unspecified, setting it to an empty
553     +   string is implementation dependent.
554     +   Note also that changing the prefix of an attribute that is known to have a
555     +   default value, does not make a new attribute with the default value and the
556     +   original prefix appear, since the `namespaceURI` and `localName` do not change.
557     +   For nodes of any type other than `ELEMENT` and `ATTRIBUTE` and nodes created
558     +   with a DOM Level 1 method, such as `createElement` from the `Document`
559     +   interface, this is always `null`.
560     +/
561     @property DOMString prefix();
562     /// ditto
563     @property void prefix(DOMString);
564     /++
565     +   The namespace URI of this node, or `null` if it is unspecified.
566     +   This is not a computed value that is the result of a namespace lookup based
567     +   on an examination of the namespace declarations in scope. It is merely the
568     +   namespace URI given at creation time.
569     +   For nodes of any type other than `ELEMENT` and `ATTRIBUTE` and nodes created
570     +   with a DOM Level 1 method, such as `Document.createElement`, this is always `null`.
571     +/
572     @property DOMString namespaceURI();
573     /// The absolute base URI of this node or null if the implementation wasn't able to obtain an absolute URI
574     @property DOMString baseURI();
575 
576     /// The value of this node, depending on its type.
577     @property DOMString nodeValue();
578     /// ditto
579     @property void nodeValue(DOMString);
580     /// Returns the text content, if there's any.
581     @property DOMString textContent();
582     /// Sets the text content, it there's any.
583     @property void textContent(DOMString);
584 
585     /++
586     +   The parent of this node. All nodes, except `Attr`, `Document`, `DocumentFragment`,
587     +   `Entity`, and `Notation` may have a parent. However, if a node has just been
588     +   created and not yet added to the tree, or if it has been removed from the tree,
589     +   this is `null`.
590     +/
591     @property Node parentNode();
592     /// A `NodeList` that contains all children of this node. If there are no children, this is a `NodeList` containing no nodes.
593     @property NodeList childNodes();
594     /// The first child of this node. If there is no such node, this returns `null`.
595     @property Node firstChild();
596     /// The last child of this node. If there is no such node, this returns `null`.
597     @property Node lastChild();
598     /// The node immediately preceding this node. If there is no such node, this returns `null`.
599     @property Node previousSibling();
600     /// The node immediately following this node. If there is no such node, this returns `null`.
601     @property Node nextSibling();
602     /++
603     +   The `Document` object associated with this node. This is also the `Document`
604     +   object used to create new nodes. When this node is a `Document` or a `DocumentType`
605     +   which is not used with any `Document` yet, this is `null`.
606     +/
607     @property Document ownerDocument();
608 
609     /// A `NamedNodeMap` containing the attributes of this node (if it is an `Element`) or `null` otherwise.
610     @property NamedNodeMap attributes();
611     /// Returns whether this node (if it is an element) has any attributes.
612     bool hasAttributes();
613 
614     /++
615     +   Inserts the node `newChild` before the existing child node `refChild`.
616     +   If `refChild` is `null`, insert `newChild` at the end of the list of children.
617     +   If `newChild` is a `DocumentFragment` object, all of its children are inserted,
618     +   in the same order, before `refChild`. If the `newChild` is already in the
619     +   tree, it is first removed.
620     +/
621     Node insertBefore(Node newChild, Node refChild);
622     /++
623     +   Replaces the child node `oldChild` with `newChild` in the list of children,
624     +   and returns the `oldChild` node.
625     +   If `newChild` is a `DocumentFragment` object, `oldChild` is replaced by
626     +   all of the `DocumentFragment` children, which are inserted in the same
627     +   order. If the `newChild` is already in the tree, it is first removed.
628     +/
629     Node replaceChild(Node newChild, Node oldChild);
630     /// Removes the child node indicated by `oldChild` from the list of children, and returns it.
631     Node removeChild(Node oldChild);
632     Node appendChild(Node newChild);
633     /// Returns whether this node has any children.
634     bool hasChildNodes();
635 
636     /++
637     +   Returns a duplicate of this node, i.e., serves as a generic copy constructor
638     +   for nodes. The duplicate node has no parent (`parentNode` is `null`) and no
639     +   user data. User data associated to the imported node is not carried over.
640     +   However, if any `UserData` handlers has been specified along with the
641     +   associated data these handlers will be called with the appropriate parameters
642     +   before this method returns.
643     +/
644     Node cloneNode(bool deep);
645     bool isSameNode(Node other);
646     bool isEqualNode(Node arg);
647 
648     /++
649     +   Puts all `Text` nodes in the full depth of the sub-tree underneath this
650     +   `Node`, including attribute nodes, into a "normal" form where only structure
651     +   (e.g., elements, comments, processing instructions, CDATA sections, and entity
652     +   references) separates `Text` nodes, i.e., there are neither adjacent `Text`
653     +   nodes nor empty `Text` nodes. This can be used to ensure that the DOM view
654     +   of a document is the same as if it were saved and re-loaded.
655     +/
656     void normalize();
657 
658     /// Tests whether the DOM implementation implements a specific feature and that feature is supported by this node.
659     bool isSupported(string feature, string version_);
660     Object getFeature(string feature, string version_);
661 
662     /++
663     +   Retrieves the object associated to a key on a this node. The object must
664     +   first have been set to this node by calling `setUserData` with the same key.
665     +/
666     UserData getUserData(string key) @trusted ;
667     /++
668     +   Associate an object to a key on this node.
669     +   The object can later be retrieved from this node by calling `getUserData` with the same key.
670     +/
671     UserData setUserData(string key, UserData data, UserDataHandler handler) @trusted ;
672 
673     /++
674     +   Compares the reference node, i.e. the node on which this method is being
675     +   called, with a node, i.e. the one passed as a parameter, with regard to
676     +   their position in the document and according to the document order.
677     +/
678     BitFlags!DocumentPosition compareDocumentPosition(Node other) @trusted;
679 
680     /++
681     +   Look up the prefix associated to the given namespace URI, starting from this node.
682     +   The default namespace declarations are ignored by this method.
683     +/
684     DOMString lookupPrefix(DOMString namespaceURI);
685     /// Look up the namespace URI associated to the given `prefix`, starting from this node.
686     DOMString lookupNamespaceURI(DOMString prefix);
687     /// This method checks if the specified `namespaceURI` is the default namespace or not.
688     bool isDefaultNamespace(DOMString namespaceURI);
689 }
690 
691 /++
692 +   The `NodeList` interface provides the abstraction of an ordered collection of
693 +   nodes, without defining or constraining how this collection is implemented.
694 +   `NodeList` objects in the DOM are live.
695 +
696 +   The items in the `NodeList` are accessible via an integral index, starting from `0`.
697 +/
698 interface NodeList {
699     /++
700     +   Returns the `index`th item in the collection. If `index` is greater than
701     +   or equal to the number of nodes in the list, this returns `null`.
702     +/
703     Node item(size_t index);
704     /++
705     +   The number of nodes in the list. The range of valid child node indices is
706     +   `0` to `length-1` inclusive.
707     +/
708     @property size_t length();
709 
710     final int opApply(int delegate(Node) @safe foreachBody)
711     {
712         for (size_t i = 0; i < length; i++)
713         {
714             auto result = foreachBody(item(i));
715             if (result) return result;
716         }
717         return 0;
718     }
719 }
720 
721 /++
722 +   Objects implementing the `NamedNodeMap` interface are used to represent collections
723 +   of nodes that can be accessed by name. Note that `NamedNodeMap` does not inherit
724 +   from `NodeList`; `NamedNodeMaps` are not maintained in any particular order.
725 +   Objects contained in an object implementing `NamedNodeMap` may also be accessed
726 +   by an ordinal index, but this is simply to allow convenient enumeration of the
727 +   contents of a `NamedNodeMap`, and does not imply that the DOM specifies an order
728 +   to these `Node`s.
729 +
730 +   `NamedNodeMap` objects in the DOM are live.
731 +/
732 interface NamedNodeMap {
733     /++
734     +   Returns the `index`th item in the collection. If `index` is greater than
735     +   or equal to the number of nodes in the list, this returns `null`.
736     +/
737     Node item(size_t index);
738     /++
739     +   The number of nodes in the list. The range of valid child node indices is
740     +   `0` to `length-1` inclusive.
741     +/
742     @property size_t length();
743 
744     final int opApply(int delegate(Node) @safe foreachBody)
745     {
746         for (size_t i = 0; i < length; i++)
747         {
748             auto result = foreachBody(item(i));
749             if (result) return result;
750         }
751         return 0;
752     }
753 
754     /// Retrieves a node specified by name.
755     Node getNamedItem(DOMString name);
756     /++
757     +   Adds a node using its `nodeName` attribute. If a node with that name is
758     +   already present in this map, it is replaced by the new one. Replacing a
759     +   node by itself has no effect.
760     +   As the `nodeName` attribute is used to derive the name which the node must
761     +   be stored under, multiple nodes of certain types (those that have a "special"
762     +   string value) cannot be stored as the names would clash. This is seen as
763     +   preferable to allowing nodes to be aliased.
764     +/
765     Node setNamedItem(Node arg);
766     /++
767     +   Removes a node specified by name. When this map contains the attributes
768     +   attached to an element, if the removed attribute is known to have a default
769     +   value, an attribute immediately appears containing the default value as
770     +   well as the corresponding namespace URI, local name, and prefix when applicable.
771     +/
772     Node removeNamedItem(DOMString name);
773 
774     /++
775     +   Retrieves a node specified by local name and namespace URI.
776     +   Per the XML Namespaces specification, applications must use the value `null`
777     +   as the `namespaceURI` parameter for methods if they wish to have no namespace.
778     +/
779     Node getNamedItemNS(DOMString namespaceURI, DOMString localName);
780     /++
781     +   Adds a node using its `namespaceURI` and `localName`. If a node with that
782     +   namespace URI and that local name is already present in this map, it is
783     +   replaced by the new one. Replacing a node by itself has no effect.
784     +   Per the XML Namespaces specification, applications must use the value `null`
785     +   as the namespaceURI parameter for methods if they wish to have no namespace.
786     +/
787     Node setNamedItemNS(Node arg);
788     /++
789     +   Removes a node specified by local name and namespace URI. A removed attribute
790     +   may be known to have a default value when this map contains the attributes attached
791     +   to an element, as returned by the attributes attribute of the `Node` interface.
792     +   If so, an attribute immediately appears containing the default value as well
793     +   as the corresponding namespace URI, local name, and prefix when applicable.
794     +   Per the XML Namespaces specification, applications must use the value `null`
795     +   as the `namespaceURI` parameter for methods if they wish to have no namespace.
796     +/
797     Node removeNamedItemNS(DOMString namespaceURI, DOMString localName);
798 }
799 
800 /++
801 +   The `CharacterData` interface extends `Node` with a set of attributes and methods
802 +   for accessing character data in the DOM. For clarity this set is defined here
803 +   rather than on each object that uses these attributes and methods. No DOM objects
804 +   correspond directly to `CharacterData`, though `Text` and others do inherit
805 +   the interface from it. All offsets in this interface start from `0`.
806 +/
807 interface CharacterData : Node {
808     @property DOMString data();
809     @property void data(DOMString);
810 
811     @property size_t length();
812 
813     /// Extracts a substring of `data` starting at `offset`, with length `count`.
814     DOMString substringData(size_t offset, size_t count);
815     /++
816     +   Append the string to the end of the character data of the node. Upon success,
817     +   data provides access to the concatenation of data and the DOMString specified.
818     +/
819     void appendData(DOMString arg);
820     /// Insert a string at the specified offset.
821     void insertData(size_t offset, DOMString arg);
822     /// Remove a range of characters from the node. Upon success, `data` and `length` reflect the change.
823     void deleteData(size_t offset, size_t count);
824     /// Replace `count` characters starting at the specified offset with the specified string.
825     void replaceData(size_t offset, size_t count, DOMString arg);
826 }
827 
828 /++
829 +   The `Attr` interface represents an attribute in an `Element` object. Typically
830 +   the allowable values for the attribute are defined in a schema associated with the document.
831 +
832 +   `Attr` objects inherit the `Node` interface, but since they are not actually
833 +   child nodes of the element they describe, the DOM does not consider them part
834 +   of the document tree. Thus, the `Node` attributes `parentNode`, `previousSibling`
835 +   and `nextSibling` have a `null` value for `Attr` objects. The DOM takes the
836 +   view that attributes are properties of elements rather than having a separate
837 +   identity from the elements they are associated with; this should make it more
838 +   efficient to implement such features as default attributes associated with all
839 +   elements of a given type. Furthermore, `Attr` nodes may not be immediate children
840 +   of a `DocumentFragment`. However, they can be associated with `Element` nodes
841 +   contained within a `DocumentFragment`. In short, users and implementors of the
842 +   DOM need to be aware that `Attr` nodes have some things in common with other
843 +   objects inheriting the `Node` interface, but they also are quite distinct.
844 +/
845 interface Attr : Node {
846     /++
847     +   Returns the _name of this attribute. If `Node.localName` is different from
848     +   `null`, this attribute is a qualified name.
849     +/
850     @property DOMString name();
851     /++
852     +   `true` if this attribute was explicitly given a value in the instance document,
853     +   `false` otherwise. If the application changed the value of this attribute
854     +   node (even if it ends up having the same value as the default value) then
855     +   it is set to `true`. The implementation may handle attributes with default
856     +   values from other schemas similarly but applications should use `Document.normalizeDocument`
857     +   to guarantee this information is up-to-date.
858     +/
859     @property bool specified();
860     /++
861     +   On retrieval, the value of the attribute is returned as a `DOMString`.
862     +   Character and general entity references are replaced with their values.
863     +   See also the method `getAttribute` on the `Element` interface.
864     +   On setting, this creates a `Text` node with the unparsed contents of the
865     +   string, i.e. any characters that an XML processor would recognize as markup
866     +   are instead treated as literal text.
867     +   See also the method `Element.setAttribute`.
868     +/
869     @property DOMString value();
870     /// ditto
871     @property void value(DOMString);
872 
873     /// The `Element` node this attribute is attached to or `null` if this attribute is not in use.
874     @property Element ownerElement();
875     /++
876     +   The type information associated with this attribute. While the type information
877     +   contained in this attribute is guarantee to be correct after loading the
878     +   document or invoking `Document.normalizeDocument`, `schemaTypeInfo` may
879     +   not be reliable if the node was moved.
880     +/
881     @property XMLTypeInfo schemaTypeInfo();
882     /++
883     +   Returns whether this attribute is known to be of type ID (i.e. to contain
884     +   an identifier for its owner element) or not. When it is and its value is
885     +   unique, the ownerElement of this attribute can be retrieved using the method
886     +   `Document.getElementById`.
887     +/
888     @property bool isId();
889 }
890 /** 
891  * Elements are the main building block of an XML document. They have a name, an associated namespace, attributes,
892  * text, and child elements.
893  */
894 interface Element : Node {
895     /// The name of the element. If `Node.localName` is different from `null`, this attribute is a qualified name.
896     @property DOMString tagName();
897 
898     /// Retrieves an attribute value by name.
899     DOMString getAttribute(DOMString name);
900     /++
901     +   Adds a new attribute. If an attribute with that name is already present in
902     +   the element, its value is changed to be that of the value parameter. This
903     +   value is a simple string; it is not parsed as it is being set. So any markup
904     +   (such as syntax to be recognized as an entity reference) is treated as
905     +   literal text, and needs to be appropriately escaped by the implementation
906     +   when it is written out. In order to assign an attribute value that contains
907     +   entity references, the user must create an `Attr` node plus any `Text` and
908     +   `EntityReference` nodes, build the appropriate subtree, and use `setAttributeNode`
909     +   to assign it as the value of an attribute.
910     +   To set an attribute with a qualified name and namespace URI, use the `setAttributeNS` method.
911     +/
912     void setAttribute(DOMString name, DOMString value);
913     /++
914     +   Removes an attribute by name. If a default value for the removed attribute
915     +   is defined in the DTD, a new attribute immediately appears with the default
916     +   value as well as the corresponding namespace URI, local name, and prefix
917     +   when applicable.
918     +   To remove an attribute by local name and namespace URI, use the `removeAttributeNS` method.
919     +/
920     void removeAttribute(DOMString name);
921 
922     /// Retrieves an attribute node by name.
923     Attr  getAttributeNode(DOMString name);
924     /++
925     +   Adds a new attribute node. If an attribute with that name (`nodeName`) is
926     +   already present in the element, it is replaced by the new one. Replacing an
927     +   attribute node by itself has no effect.
928     +   To add a new attribute node with a qualified name and namespace URI, use
929     +   the `setAttributeNodeNS` method.
930     +/
931     Attr setAttributeNode(Attr newAttr);
932     /++
933     +   Removes the specified attribute node. If a default value for the removed attribute
934     +   is defined in the DTD, a new attribute immediately appears with the default
935     +   value as well as the corresponding namespace URI, local name, and prefix
936     +   when applicable.
937     +/
938     Attr removeAttributeNode(Attr oldAttr);
939 
940     /++
941     +   Retrieves an attribute value by local name and namespace URI.
942     +   Per the XML Namespaces specification, applications must use the value `null`
943     +   as the `namespaceURI` parameter for methods if they wish to have no namespace.
944     +/
945     DOMString getAttributeNS(DOMString namespaceURI, DOMString localName);
946     /++
947     +   Adds a new attribute. If an attribute with the same local name and namespace
948     +   URI is already present on the element, its prefix is changed to be the prefix
949     +   part of the qualifiedName, and its value is changed to be the value parameter.
950     +   This value is a simple string; it is not parsed as it is being set. So any markup
951     +   (such as syntax to be recognized as an entity reference) is treated as
952     +   literal text, and needs to be appropriately escaped by the implementation
953     +   when it is written out. In order to assign an attribute value that contains
954     +   entity references, the user must create an `Attr` node plus any `Text` and
955     +   `EntityReference` nodes, build the appropriate subtree, and use `setAttributeNode`
956     +   to assign it as the value of an attribute.
957     +   Per the XML Namespaces specification, applications must use the value `null`
958     +   as the `namespaceURI` parameter for methods if they wish to have no namespace.
959     +/
960     void setAttributeNS(DOMString namespaceURI, DOMString qualifiedName, DOMString value);
961     /++
962     +   Removes an attribute by local name and namespace URI. If a default value
963     +   for the removed attribute is defined in the DTD, a new attribute immediately
964     +   appears with the default value as well as the corresponding namespace URI,
965     +   local name, and prefix when applicable.
966     +   Per the XML Namespaces specification, applications must use the value `null`
967     +   as the `namespaceURI` parameter for methods if they wish to have no namespace.
968     +/
969     void removeAttributeNS(DOMString namespaceURI, DOMString localName);
970 
971     /++
972     +   Retrieves an `Attr` node by local name and namespace URI.
973     +   Per the XML Namespaces specification, applications must use the value `null`
974     +   as the `namespaceURI` parameter for methods if they wish to have no namespace.
975     +/
976     Attr getAttributeNodeNS(DOMString namespaceURI, DOMString localName);
977     /++
978     +   Adds a new attribute. If an attribute with that local name and that namespace
979     +   URI is already present in the element, it is replaced by the new one. Replacing
980     +   an attribute node by itself has no effect.
981     +   Per the XML Namespaces specification, applications must use the value `null`
982     +   as the `namespaceURI` parameter for methods if they wish to have no namespace.
983     +/
984     Attr setAttributeNodeNS(Attr newAttr);
985 
986     /// Returns `true` when an attribute with a given `name` is specified on this element or has a default value, `false` otherwise.
987     bool hasAttribute(DOMString name);
988     /++
989     +   Returns `true` when an attribute with a given `localName` and `namespaceURI`
990     +   is specified on this element or has a default value, `false` otherwise.
991     +   Per the XML Namespaces specification, applications must use the value `null`
992     +   as the `namespaceURI` parameter for methods if they wish to have no namespace.
993     +/
994     bool hasAttributeNS(DOMString namespaceURI, DOMString localName);
995 
996     /++
997     +   If the parameter `isId` is `true`, this method declares the specified
998     +   attribute to be a user-determined ID attribute. This affects the value of
999     +   `Attr.isId` and the behavior of `Document.getElementById`, but does not
1000     +   change any schema that may be in use, in particular this does not affect
1001     +   the `Attr.schemaTypeInfo` of the specified `Attr` node. Use the value `false`
1002     +   for the parameter `isId` to undeclare an attribute for being a user-determined ID attribute.
1003     +/
1004     void setIdAttribute(DOMString name, bool isId);
1005     /// ditto
1006     void setIdAttributeNS(DOMString namespaceURI, DOMString localName, bool isId);
1007     /// ditto
1008     void setIdAttributeNode(Attr idAttr, bool isId);
1009 
1010     /// Returns a `NodeList` of all descendant `Element`s with a given tag name, in document order.
1011     NodeList getElementsByTagName(DOMString name);
1012     /// Returns a `NodeList` of all the descendant `Element`s with a given local name and namespace URI in document order.
1013     NodeList getElementsByTagNameNS(DOMString namespaceURI, DOMString localName);
1014 
1015     /// The type information associated with this element.
1016     @property XMLTypeInfo schemaTypeInfo();
1017 }
1018 
1019 /++
1020 +   The `Text` interface inherits from `CharacterData` and represents the textual
1021 +   content (termed character data in XML) of an `Element` or `Attr`. If there is
1022 +   no markup inside an element's content, the text is contained in a single object
1023 +   implementing the `Text` interface that is the only child of the element. If
1024 +   there is markup, it is parsed into the information items (elements, comments,
1025 +   etc.) and `Text` nodes that form the list of children of the element.
1026 +/
1027 interface Text : CharacterData {
1028     /++
1029     +   Breaks this node into two nodes at the specified `offset`, keeping both
1030     +   in the tree as siblings. After being split, this node will contain all
1031     +   the content up to the `offset` point. A new node of the same type, which
1032     +   contains all the content at and after the `offset` point, is returned.
1033     +   If the original node had a parent node, the new node is inserted as the
1034     +   next sibling of the original node. When the `offset` is equal to the length
1035     +   of this node, the new node has no data.
1036     +/
1037     Text splitText(size_t offset);
1038 
1039     /// Returns whether this text node contains element content whitespace, often abusively called "ignorable whitespace".
1040     @property bool isElementContentWhitespace();
1041     /// Returns the combined data of all direct text node siblings.
1042     @property DOMString wholeText();
1043     /// Couldn't find in DOM documentation, but leavint it there.
1044     Text replaceWholeText(DOMString content);
1045 }
1046 
1047 /++
1048 +   This interface inherits from `CharacterData` and represents the content of a
1049 +   comment, i.e., all the characters between the starting '<!--' and ending '-->'.
1050 +/
1051 interface Comment : CharacterData {
1052 }
1053 
1054 /++
1055 +   The `TypeInfo` interface represents a type referenced from `Element` or `Attr`
1056 +   nodes, specified in the schemas associated with the document. The type is a
1057 +   pair of a namespace URI and name properties, and depends on the document's schema.
1058 +/
1059 interface XMLTypeInfo {
1060     @property DOMString typeName();
1061     @property DOMString typeNamespace();
1062 
1063     bool isDerivedFrom(DOMString typeNamespaceArg, DOMString typeNameArg, DerivationMethod derivationMethod);
1064 }
1065 
1066 /// DOMError is an interface that describes an error.
1067 interface DOMError {
1068     @property ErrorSeverity severity();
1069     @property DOMString message();
1070     @property DOMString type();
1071     @property Object relatedException();
1072     @property Object relatedData();
1073     @property DOMLocator location();
1074 }
1075 
1076 /// `DOMLocator` is an interface that describes a location (e.g. where an error occurred).
1077 interface DOMLocator {
1078     @property long lineNumber();
1079     @property long columnNumber();
1080     @property long byteOffset();
1081     @property Node relatedNode();
1082     @property DOMString uri();
1083 }
1084 
1085 /++
1086 +   The `DOMConfiguration` interface represents the configuration of a document
1087 +   and maintains a table of recognized parameters. Using the configuration, it
1088 +   is possible to change `Document.normalizeDocument` behavior, such as replacing
1089 +   the `CDATASection` nodes with `Text` nodes or specifying the type of the schema
1090 +   that must be used when the validation of the `Document` is requested.
1091 +/
1092 interface DOMConfiguration {
1093     void setParameter(string name, UserData value) @trusted;
1094     UserData getParameter(string name) @trusted;
1095     bool canSetParameter(string name, UserData value) @trusted;
1096     @property DOMStringList parameterNames();
1097 }
1098 
1099 /++
1100 +   CDATA sections are used to escape blocks of text containing characters that would
1101 +   otherwise be regarded as markup. The only delimiter that is recognized in a CDATA
1102 +   section is the "]]>" string that ends the CDATA section. CDATA sections cannot be nested.
1103 +   Their primary purpose is for including material such as XML fragments, without
1104 +   needing to escape all the delimiters.
1105 +
1106 +   The `CDATASection` interface inherits from the `CharacterData` interface through
1107 +   the `Text` interface. Adjacent `CDATASection` nodes are not merged by use of the
1108 +   normalize method of the `Node` interface.
1109 +/
1110 interface CDATASection : Text {
1111 }
1112 
1113 /++
1114 +   Each `Document` has a `doctype` attribute whose value is either `null` or a
1115 +   `DocumentType` object. The `DocumentType` interface in the DOM Core provides
1116 +   an interface to the list of entities that are defined for the document, and
1117 +   little else because the effect of namespaces and the various XML schema efforts
1118 +   on DTD representation are not clearly understood as of this writing.
1119 +
1120 +   DOM Level 3 doesn't support editing `DocumentType` nodes. `DocumentType` nodes are read-only.
1121 +/
1122 interface DocumentType : Node {
1123     /// The name of DTD; i.e., the name immediately following the `DOCTYPE` keyword.
1124     @property DOMString name();
1125     /++
1126     +   A `NamedNodeMap` containing the general entities, both external and internal,
1127     +   declared in the DTD. Parameter entities are not contained. Duplicates are discarded.
1128     +/
1129     @property NamedNodeMap entities();
1130     /++
1131     +   A `NamedNodeMap` containing the notations declared in the DTD. Duplicates are discarded.
1132     +   Every node in this map also implements the `Notation` interface.
1133     +/
1134     @property NamedNodeMap notations();
1135     /// The public identifier of the external subset.
1136     @property DOMString publicId();
1137     /// The system identifier of the external subset. This may be an absolute URI or not.
1138     @property DOMString systemId();
1139     /++
1140     +   The internal subset as a string, or `null` if there is none.
1141     +   This is does not contain the delimiting square brackets.
1142     +
1143     +   Note:
1144     +   The actual content returned depends on how much information is available
1145     +   to the implementation. This may vary depending on various parameters,
1146     +   including the XML processor used to build the document.
1147     +/
1148     @property DOMString internalSubset();
1149 }
1150 
1151 /++
1152 +   This interface represents a notation declared in the DTD. A notation either
1153 +   declares, by name, the format of an unparsed entity or is used for formal
1154 +   declaration of processing instruction targets. The `nodeName` attribute
1155 +   inherited from `Node` is set to the declared name of the notation.
1156 +
1157 +   The DOM Core does not support editing `Notation` nodes; they are therefore readonly.
1158 +
1159 +   A `Notation` node does not have any parent.
1160 +/
1161 interface Notation : Node {
1162     /// The public identifier of this notation. If the public identifier was not specified, this is `null`.
1163     @property DOMString publicId();
1164     /++
1165     +   The system identifier of this notation. If the system identifier was not
1166     +   specified, this is `null`. This may be an absolute URI or not.
1167     +/
1168     @property DOMString systemId();
1169 }
1170 
1171 /++
1172 +   This interface represents a known entity, either parsed or unparsed, in an XML
1173 +   document. Note that this models the entity itself not the entity declaration.
1174 +
1175 +   The `nodeName` attribute that is inherited from `Node` contains the name of the entity.
1176 +
1177 +   An XML processor may choose to completely expand entities before the structure
1178 +   model is passed to the DOM; in this case there will be no `EntityReference`
1179 +   nodes in the document tree.
1180 +
1181 +   DOM Level 3 does not support editing `Entity` nodes; if a user wants to make
1182 +   changes to the contents of an `Entity`, every related `EntityReference` node
1183 +   has to be replaced in the structure model by a clone of the `Entity`'s contents,
1184 +   and then the desired changes must be made to each of those clones instead.
1185 +   `Entity` nodes and all their descendants are readonly.
1186 +
1187 +   An `Entity` node does not have any parent.
1188 +/
1189 interface Entity : Node {
1190     /// The public identifier associated with the entity if specified, and `null` otherwise.
1191     @property DOMString publicId();
1192     /++
1193     +   The system identifier associated with the entity if specified, and `null` otherwise.
1194     +   This may be an absolute URI or not.
1195     +/
1196     @property DOMString systemId();
1197     /// For unparsed entities, the name of the `Notation` for the entity. For parsed entities, this is `null`.
1198     @property DOMString notationName();
1199     /++
1200     +   An attribute specifying the encoding used for this entity at the time of
1201     +   parsing, when it is an external parsed entity. This is `null` if it an
1202     +   entity from the internal subset or if it is not known.
1203     +/
1204     @property DOMString inputEncoding();
1205     /++
1206     +   An attribute specifying, as part of the text declaration, the encoding of
1207     +   this entity, when it is an external parsed entity. This is `null` otherwise.
1208     +/
1209     @property DOMString xmlEncoding();
1210     /++
1211     +   An attribute specifying, as part of the text declaration, the version
1212     +   number of this entity, when it is an external parsed entity. This is
1213     +   `null` otherwise.
1214     +/
1215     @property DOMString xmlVersion();
1216 }
1217 
1218 /++
1219 +   `EntityReference` nodes may be used to represent an entity reference in the tree.
1220 +   When an `EntityReference` node represents a reference to an unknown entity, the
1221 +   node has no children and its replacement value, when used by `Attr.value` for example, is empty.
1222 +
1223 +   As for `Entity` nodes, `EntityReference` nodes and all their descendants are readonly.
1224 +/
1225 interface EntityReference : Node {
1226 }
1227 
1228 /++
1229 +   The `ProcessingInstruction` interface represents a "processing instruction",
1230 +   used in XML as a way to keep processor-specific information in the text of the document.
1231 +/
1232 interface ProcessingInstruction : Node {
1233     /++
1234     +   The target of this processing instruction. XML defines this as being the
1235     +   first token following the markup that begins the processing instruction.
1236     +/
1237     @property DOMString target();
1238     /++
1239     +   The content of this processing instruction. This is from the first non white
1240     +   space character after the target to the character immediately preceding the `?>`.
1241     +/
1242     @property DOMString data();
1243     /// ditto
1244     @property void data(DOMString);
1245 }