B
    n&=[8                 @   s   d dl mZmZmZ d dlmZ ddlmZmZm	Z	 dZ
eedfeeee	d dfgB dfeeee	d d	fe	d d
fgB dfee	d dfe	d dfgdfee	d dfe	d dfgdfdZG dd deZG dd deZG dd deZdS )    )absolute_importdivisionunicode_literals)	text_type   )scopingElementstableInsertModeElements
namespacesNFhtmlbuttonZolZultableoptgroupoptionT)Nr   listr   Zselectc               @   sb   e Zd ZdZdd Zdd Zdd Zdd	 ZdddZdd Z	dd Z
dd Zdd Zdd Zd
S )NodezRepresents an item in the treec             C   s(   || _ d| _d| _i | _g | _g | _dS )zRCreates a Node

        :arg name: The tag name associated with the node

        N)nameparentvalue
attributes
childNodesZ_flags)selfr    r   9lib/python3.7/site-packages/html5lib/treebuilders/base.py__init__   s    zNode.__init__c             C   s:   d dd | j D }|r,d| j|f S d| j S d S )N c             S   s   g | ]\}}d ||f qS )z%s="%s"r   ).0r   r   r   r   r   
<listcomp>.   s   z Node.__str__.<locals>.<listcomp>z<%s %s>z<%s>)joinr   itemsr   )r   ZattributesStrr   r   r   __str__-   s
    
zNode.__str__c             C   s
   d| j  S )Nz<%s>)r   )r   r   r   r   __repr__6   s    zNode.__repr__c             C   s   t dS )z[Insert node as a child of the current node

        :arg node: the node to insert

        N)NotImplementedError)r   noder   r   r   appendChild9   s    zNode.appendChildNc             C   s   t dS )aB  Insert data as text in the current node, positioned before the
        start of node insertBefore or to the end of the node's text.

        :arg data: the data to insert

        :arg insertBefore: True if you want to insert the text before the node
            and False if you want to insert it after the node

        N)r!   )r   datainsertBeforer   r   r   
insertTextA   s    
zNode.insertTextc             C   s   t dS )a  Insert node as a child of the current node, before refNode in the
        list of child nodes. Raises ValueError if refNode is not a child of
        the current node

        :arg node: the node to insert

        :arg refNode: the child node to insert the node before

        N)r!   )r   r"   ZrefNoder   r   r   r%   M   s    
zNode.insertBeforec             C   s   t dS )zhRemove node from the children of the current node

        :arg node: the child node to remove

        N)r!   )r   r"   r   r   r   removeChildY   s    zNode.removeChildc             C   s$   x| j D ]}|| qW g | _ dS )zMove all the children of the current node to newParent.
        This is needed so that trees that don't store text as nodes move the
        text in the correct way

        :arg newParent: the node to move all this node's children to

        N)r   r#   )r   Z	newParentZchildr   r   r   reparentChildrena   s    	zNode.reparentChildrenc             C   s   t dS )zReturn a shallow copy of the current node i.e. a node with the same
        name and attributes but with no parent or child nodes
        N)r!   )r   r   r   r   	cloneNoden   s    zNode.cloneNodec             C   s   t dS )zFReturn true if the node has children or text, false otherwise
        N)r!   )r   r   r   r   
hasContentt   s    zNode.hasContent)N)__name__
__module____qualname____doc__r   r   r    r#   r&   r%   r'   r(   r)   r*   r   r   r   r   r      s   	
r   c               @   s   e Zd Zdd Zdd ZdS )ActiveFormattingElementsc             C   sf   d}|t krVxH| d d d D ]6}|t kr*P | ||r>|d7 }|dkr| | P qW t| | d S )Nr         )Marker
nodesEqualremover   append)r   r"   Z
equalCountelementr   r   r   r6   {   s    
zActiveFormattingElements.appendc             C   s$   |j |j ksdS |j|jks dS dS )NFT)	nameTupler   )r   Znode1Znode2r   r   r   r4      s
    z#ActiveFormattingElements.nodesEqualN)r+   r,   r-   r6   r4   r   r   r   r   r/   z   s   r/   c               @   s   e Zd ZdZdZdZdZdZdZdd Z	dd Z
d+ddZd	d
 Zdd Zdd Zdd Zdd Zd,ddZdd Zdd Zdd ZeeeZdd Zdd Zd-dd Zd!d" Zd.d#d$Zd%d& Zd'd( Zd)d* ZdS )/TreeBuildera  Base treebuilder implementation

    * documentClass - the class to use for the bottommost node of a document
    * elementClass - the class to use for HTML Elements
    * commentClass - the class to use for comments
    * doctypeClass - the class to use for doctypes

    Nc             C   s   |rd| _ nd| _ |   dS )zmCreate a TreeBuilder

        :arg namespaceHTMLElements: whether or not to namespace HTML elements

        zhttp://www.w3.org/1999/xhtmlN)defaultNamespacereset)r   ZnamespaceHTMLElementsr   r   r   r      s    zTreeBuilder.__init__c             C   s.   g | _ t | _d | _d | _d| _|  | _d S )NF)openElementsr/   activeFormattingElementsZheadPointerZformPointerinsertFromTabledocumentClassdocument)r   r   r   r   r;      s    zTreeBuilder.resetc             C   s   t |d}|s2t|tr$td |f}t|ts2tt| \}}xFt| jD ]8}|r^||kr^dS |sp|j	|krpdS ||j	|kA rJdS qJW dstd S )Nr8   r
   TF)
hasattr
isinstancer   r	   tupleAssertionErrorlistElementsMapreversedr<   r8   )r   targetZvariantZ	exactNodeZlistElementsinvertr"   r   r   r   elementInScope   s    

zTreeBuilder.elementInScopec             C   s   | j s
d S t| j d }| j | }|tks4|| jkr8d S x6|tkrn|| jkrn|dkrZd}P |d8 }| j | }q:W xR|d7 }| j | }| }| d|j|j|jd}|| j |< || j d krrP qrW d S )Nr1   r   r0   ZStartTag)typer   	namespacer$   )	r=   lenr3   r<   r)   insertElementr   rK   r   )r   ientryZcloner7   r   r   r   #reconstructActiveFormattingElements   s.    


z/TreeBuilder.reconstructActiveFormattingElementsc             C   s,   | j  }x| j r&|tkr&| j  }qW d S )N)r=   popr3   )r   rO   r   r   r   clearActiveFormattingElements  s    
z)TreeBuilder.clearActiveFormattingElementsc             C   s8   x2| j ddd D ]}|tkr"P q|j|kr|S qW dS )zCheck if an element exists between the end of the active
        formatting elements and the last marker. If it does, return it, else
        return falseNr0   F)r=   r3   r   )r   r   itemr   r   r   !elementInActiveFormattingElements  s    
z-TreeBuilder.elementInActiveFormattingElementsc             C   s&   |  |}| j| | j| d S )N)createElementr<   r6   r@   r#   )r   tokenr7   r   r   r   
insertRoot  s    
zTreeBuilder.insertRootc             C   s6   |d }|d }|d }|  |||}| j| d S )Nr   publicIdsystemId)doctypeClassr@   r#   )r   rV   r   rX   rY   Zdoctyper   r   r   insertDoctype   s
    zTreeBuilder.insertDoctypec             C   s*   |d kr| j d }|| |d  d S )Nr0   r$   )r<   r#   commentClass)r   rV   r   r   r   r   insertComment(  s    
zTreeBuilder.insertCommentc             C   s0   |d }| d| j}| ||}|d |_|S )z.Create an element but don't insert it anywherer   rK   r$   )getr:   elementClassr   )r   rV   r   rK   r7   r   r   r   rU   -  s
    
zTreeBuilder.createElementc             C   s   | j S )N)_insertFromTable)r   r   r   r   _getInsertFromTable5  s    zTreeBuilder._getInsertFromTablec             C   s    || _ |r| j| _n| j| _dS )zsSwitch the function used to insert an element from the
        normal one to the misnested table one and back againN)r`   insertElementTablerM   insertElementNormal)r   r   r   r   r   _setInsertFromTable8  s    
zTreeBuilder._setInsertFromTablec             C   sb   |d }t |tstd| |d| j}| ||}|d |_| jd | | j	| |S )Nr   zElement %s not unicoderK   r$   r0   )
rB   r   rD   r^   r:   r_   r   r<   r#   r6   )r   rV   r   rK   r7   r   r   r   rc   C  s    
zTreeBuilder.insertElementNormalc             C   s`   |  |}| jd jtkr$| |S |  \}}|dkrD|| n||| | j| |S )z-Create an element and insert it into the treer0   N)	rU   r<   r   r   rc   getTableMisnestedNodePositionr#   r%   r6   )r   rV   r7   r   r%   r   r   r   rb   M  s    

zTreeBuilder.insertElementTablec             C   sV   |dkr| j d }| jr.| jr:| j d jtkr:|| n|  \}}||| dS )zInsert text data.Nr0   )r<   r>   r   r   r&   re   )r   r$   r   r%   r   r   r   r&   ]  s    

zTreeBuilder.insertTextc             C   sv   d}d}d}x(| j ddd D ]}|jdkr|}P qW |rd|jrL|j}|}qn| j | j |d  }n
| j d }||fS )zsGet the foster parent element, and sibling to insert before
        (or None) when inserting a misnested table nodeNr0   r   r1   r   )r<   r   r   index)r   Z	lastTableZfosterParentr%   Zelmr   r   r   re   l  s    

z)TreeBuilder.getTableMisnestedNodePositionc             C   s8   | j d j}|tdkr4||kr4| j   | | d S )Nr0   )ZddZdtZlir   r   pZrpZrt)r<   r   	frozensetrQ   generateImpliedEndTags)r   Zexcluder   r   r   r   ri     s
    
z"TreeBuilder.generateImpliedEndTagsc             C   s   | j S )zReturn the final tree)r@   )r   r   r   r   getDocument  s    zTreeBuilder.getDocumentc             C   s   |   }| jd | |S )zReturn the final fragmentr   )fragmentClassr<   r(   )r   Zfragmentr   r   r   getFragment  s    zTreeBuilder.getFragmentc             C   s   t dS )zSerialize the subtree of node in the format required by unit tests

        :arg node: the node from which to start serializing

        N)r!   )r   r"   r   r   r   testSerializer  s    zTreeBuilder.testSerializer)N)N)N)N)r+   r,   r-   r.   r?   r_   r\   rZ   rk   r   r;   rI   rP   rR   rT   rW   r[   r]   rU   ra   rd   propertyr>   rc   rb   r&   re   ri   rj   rl   rm   r   r   r   r   r9      s6   
.
	




r9   )Z
__future__r   r   r   Zsixr   Z	constantsr   r   r	   r3   rh   setrE   objectr   r   r/   r9   r   r   r   r   <module>   s   
c