# encoding: utf-8 """ https://dom.spec.whatwg.org/ Other URL: - https://fr.wikipedia.org/wiki/Document_Object_Model """ from enum import Enum from tree import Node, Tree # Move exceptions in a specific file ? class DOMException(Exception): pass class IndexSizeError(DOMException): pass # Move Enums in a specific file ? class NodeFilter(Enum): SHOW_ALL = 0xffffffff class ShadowRootMode(Enum): open = 1 closed = 2 class SlotAssignmentMode(Enum): manual = 1 named = 2 class Document(Node): def __init__(self): super().__init__(self) self._implementation = None self._URL = None self._documentURI = None self._compatMode = None self._characterSet = None self._charset = None self._inputEncoding = None self._contentType = None self._doctype = None self._documentElement = None @property def implementation(self): return self._implementation @property def URL(self): return self._URL @property def documentURI(self): return self._documentURI @property def compatMode(self): return self._compatMode @property def characterSet(self): return self._characterSet @property def charset(self): return self._charset @property def inputEncoding(self): return self._inputEncoding @property def contentType(self): return self._contentType @property def doctype(self): return self._doctype @property def documentElement(self): return self._documentElement def getElementsByTagName(self, qualifiedName): # TODO pass def getElementsByTagNameNS(self, namespace, localName): # TODO pass def getElementsByClassName(self, classNames): # TODO pass def createElement(self, localName, options={}): # TODO pass def createElementNS(self, namespace, qualifiedName, options={}): # TODO pass def createDocumentFragment(self): # TODO pass def createTextNode(self, data): # TODO pass def createCDATASection(self, data): # TODO pass def createComment(self, data): # TODO pass def createProcessingInstruction(self, target, data): # TODO pass def importNode(self, node, deep=False): # TODO pass def adoptNode(self, node): # TODO pass def createAttribute(self, localName): # TODO pass def createAttributeNS(self, namespace, qualifiedName): # TODO pass def createEvent(self, interface): # TODO pass def createRange(self): # TODO pass def createNodeIterator(self, root, whatToShow=0xffffffff, filter=None): # TODO pass def createTreeWalker(self, root, whatToShow=0xffffffff, filter=None): # TODO pass class DocumentType(Node): def __init__(self): super().__init__(self) self._name = None self._publicId = None self._systemId = None @property def length(self): return 0 @property def name(self): return self._name @property def publicId(self): return self._publicId @property def systemId(self): return self._systemId class DocumentFragment(Node): def __init__(self): super().__init__(self) class Element(Node): def __init__(self): super().__init__(self) self._namespaceURI = None self._prefix = None self._localName = None self._tagName = None self._classList = None self._attributes = [] self._shadowRoot = None self.id = None self.className = None self.slot = None @property def namespaceURI(self): return self.namespaceURI @property def prefix(self): return self._prefix @property def localName(self): return self._localName @property def tagName(self): return self._tagName @property def classList(self): return self._classList @property def attributes(self): return self._attributes @property def shadowRoot(self): return self._shadowRoot def hasAttributes(self): return len(self._attributes) > 0 def getAttributeNames(self): # TODO pass def getAttribute(self, qualifiedName): # TODO pass def getAttributeNS(self, namespace, localName): # TODO pass def setAttribute(self, qualifiedName, value): # TODO pass def setAttributeNS(self, namespace, localName, value): # TODO pass def removeAttribute(self, qualifiedName): # TODO pass def removeAttributeNS(self, namespace, localName): # TODO pass def toggleAttribute(self, qualifiedName, force): # TODO pass def hasAttribute(self, qualifiedName): # TODO pass def hasAttributeNS(self, namespace, localName): # TODO pass def getAttributeNode(self, qualifiedName): # TODO pass def getAttributeNodeNS(self, namespace, localName): # TODO pass def setAttributeNode(self, qualifiedName, value): # TODO pass def setAttributeNodeNS(self, namespace, localName, value): # TODO pass def removeAttributeNode(self, qualifiedName): # TODO pass def attachShadow(self, init): # TODO pass def closest(self, namespace, selectors): # TODO pass def matches(self, namespace, selectors): # TODO pass def webkitMatchesSelector(self, selectors): # TODO pass def getElementsByTagName(self, qualifiedName): # TODO pass def getElementsByTagNameNS(self, namespace, localName): # TODO pass def getElementsByClassName(self, classNames): # TODO pass def insertAdjacentElement(self, where, element): # TODO pass def insertAdjacentText(self, where, data): # TODO pass def in_a_document_tree(self): """ An element is in a document tree if its root is a document. """ return isinstance(self.root, Document) def in_a_document(self): """ An element is in a document if it is in a document tree. """ return self.in_a_document_tree() def connected(self): """ An element is connected if its shadow-including root is a document. The shadow-including root of an object is its root’s host’s shadow-including root, if the object’s root is a shadow root; otherwise its root. """ if isinstance(self.root, ShadowRoot): return self.root.host.root return self.root class CharacterData(Node): def __init__(self): super().__init__(self) self.data = "" @property def length(self): return len(self.data) def _verify_offset(self, offset): if offset > self.length: raise(IndexSizeError( f"Given offset ({offset}) is bigger than data length ({self.length})." )) def sub_string(self, offset, count): # TODO self.verify_offset(offset) def append_data(self, data): # TODO self.data += data def insert_data(self, offset, data): # TODO self.verify_offset(offset) def delete_data(self, offset, count): # TODO self.verify_offset(offset) def replace_data(self, offset, count, data): # TODO self.verify_offset(offset) class Attr(Node): def __init__(self): super().__init__(self) self._namespaceURI = None self._prefix = None self._localName = None self._name = None self._value = None self._ownerElement = None self._specified = None @property def length(self): return 0 @property def namespaceURI(self): return self._namespaceURI @property def prefix(self): return self._prefix @property def localName(self): return self._localName @property def name(self): return self._name @property def value(self): return self._value @property def ownerElement(self): return self._ownerElement @property def specified(self): return self._specified class ShadowRoot(DocumentFragment): def __init__(self): super().__init__(self) self._mode = None self._delegateFocus = None self._slotAssignment = None self._host = None self.onslotchange = None @property def mode(self): return self._mode @property def delegateFocus(self): return self._delegateFocus @property def slotAssignment(self): return self._slotAssignment @property def host(self): return self._host @property def namespaceURI(self): return self._namespaceURI class Text(CharacterData): def __init__(self, data=""): super().__init__(self) self.data = data @property def wholeText(self): # TODO pass def splitText(self, offset): # TODO pass class CDATASection(Text): pass class ProcessingInstruction(CharacterData): def __init__(self): super().__init__(self) self._target = None @property def target(self): return self._target class Comment(CharacterData): def __init__(self, data=""): super().__init__(self) self.data = data class NodeTree(Tree): """ A node tree is constrained as follows, expressed as a relationship between a node and its potential children: Document In tree order 1. Zero or more ProcessingInstruction or Comment nodes. 2. Optionally one DocumentType node. 3. Zero or more ProcessingInstruction or Comment nodes. 4. Optionally one Element node. 5. Zero or more ProcessingInstruction or Comment nodes. DocumentFragment Element Zero or more Element or CharacterData nodes. DocumentType CharacterData Attr No children. """ pass class DocumentTree: """ A document tree is a node tree whose root is a document. """ def __init__(self): super().__init__(self) self.root = Document() class ShadowTree: """ A shadow tree is a node tree whose root is a shadow root. A shadow root is always attached to another node tree through its host. A shadow tree is therefore never alone. The node tree of a shadow root’s host is sometimes referred to as the light tree. """ def __init__(self): super().__init__(self) self.root = ShadowRoot()