547 lines
11 KiB
Python
547 lines
11 KiB
Python
# 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()
|