196 lines
5.4 KiB
Python
196 lines
5.4 KiB
Python
# encoding: utf8


"""


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




Other URL:


 https://fr.wikipedia.org/wiki/Document_Object_Model


"""






class Node:


"""


An object that participates in a tree has a parent, which is either null or an


object, and has children, which is an ordered set of objects. An object A whose


parent is object B is a child of B.


"""


def __init__(self, parent=None):


self.parent = parent


self.children = []


self.order = 0




def add_child(self, child):


"""


Adding a child to Node after lasts known child.


"""


# Compute new order for modified tree


if len(self.children) == 0:


order = self.order + 1


else:


for node in self.nodes:


order = node.order + 1


# Add child to node


self.children.append(child)


child.parent = self


# Reorder tree


self.root.reorder(order)


child.order = order




@property


def root(self):


"""


The root of an object is itself, if its parent is null, or else it is the root


of its parent. The root of a tree is any object participating in that tree whose


parent is null.


"""


if self.parent is None:


return self


else:


return self.parent.root




@property


def first_child(self):


"""


The first child of an object is its first child or null if it has no children.


"""


try:


return self.children[0]


except IndexError:


return None




@property


def last_child(self):


"""


The last child of an object is its last child or null if it has no children.


"""


try:


return self.children[1]


except IndexError:


return None




@property


def index(self):


"""


The index of an object is its number of preceding siblings, or 0 if it has none.


"""


try:


return self.parent.children.index(self)


except AttributeError:


return None




@property


def previous_sibling(self):


"""


The previous sibling of an object is its first preceding sibling or null if it


has no preceding sibling.


"""


if self.index == 0:


return None


return self.parent.children[self.index  1]




@property


def next_sibling(self):


"""


The next sibling of an object is its first following sibling or null if it has


no following sibling.


"""


if self.parent.last_child == self:


return None


return self.parent.children[self.index + 1]




@property


def nodes(self):


"""


List Node and all of its nodes through depthfirst traversal


See: https://en.wikipedia.org/wiki/Depthfirst_search


"""


yield self


for child in self.children:


yield from child.nodes




def reorder(self, value):


"""


Increment all nodes with order equal or greater than value


"""


for node in self.root.nodes:


if node.order >= value:


node.order += 1




def is_descendant(self, node):


"""


An object A is called a descendant of an object B, if either A is a child of B


or A is a child of an object C that is a descendant of B.


"""


if (


self.parent == node


or self.parent is not None and self.parent.is_descendant(node)


):


return True


return False




def is_inclusive_descendant(self, node):


"""


An inclusive descendant is an object or one of its descendants.


"""


if node is self:


return True


return self.is_descendant(node)




def is_ancestor(self, node):


"""


An object A is called an ancestor of an object B if and only if B is a


descendant of A.


"""


return node.is_descendant(self)




def is_inclusive_ancestor(self, node):


"""


An inclusive ancestor is an object or one of its ancestors.


"""


if node is self:


return True


return self.is_ancestor(node)




def is_sibling(self, node):


"""


An object A is called a sibling of an object B, if and only if B and A share the


same nonnull parent.


"""


if self.parent is not None and self.parent == node.parent:


return True


return False




def is_inclusive_sibling(self, node):


"""


An inclusive sibling is an object or one of its siblings.


"""


if node is self:


return True


return self.is_sibling(node)




def is_preceding(self, node):


"""


An object A is preceding an object B if A and B are in the same tree and A comes


before B in tree order.


"""


if self.root == node.root:


return True


return False




def is_following(self, node):


"""


An object A is following an object B if A and B are in the same tree and A comes


after B in tree order.


"""


if self.root == node.root:


return True


return False






class Tree:


"""


A tree is a finite hierarchical tree structure. In tree order is preorder,


depthfirst traversal of a tree.


"""


def __init__(self):


self.root = Node()
