o
    V=^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	d dfhB dfeee	d d	fe	d d
fh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   </usr/lib/python3/dist-packages/html5lib/treebuilders/base.py__init__   s   
zNode.__init__c                 C   s6   d dd | j D }|rd| j|f S d| j 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><%s>)joinr   itemsr   )r   ZattributesStrr   r   r   __str__-   s   

zNode.__str__c                 C   s
   d| j  S )Nr   )r   r   r   r   r   __repr__6   s   
zNode.__repr__c                 C      t )z[Insert node as a child of the current node

        :arg node: the node to insert

        NotImplementedErrorr   noder   r   r   appendChild9      zNode.appendChildNc                 C   r#   )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

        r$   )r   datainsertBeforer   r   r   
insertTextA      
zNode.insertTextc                 C   r#   )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

        r$   )r   r'   ZrefNoder   r   r   r+   M   r-   zNode.insertBeforec                 C   r#   )zhRemove node from the children of the current node

        :arg node: the child node to remove

        r$   r&   r   r   r   removeChildY   r)   zNode.removeChildc                 C   s    | j D ]}|| q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	newParentchildr   r   r   reparentChildrena   s   
	
zNode.reparentChildrenc                 C   r#   )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
        r$   r!   r   r   r   	cloneNoden   s   zNode.cloneNodec                 C   r#   )zFReturn true if the node has children or text, false otherwise
        r$   r!   r   r   r   
hasContentt   s   zNode.hasContentN)__name__
__module____qualname____doc__r   r    r"   r(   r,   r+   r.   r0   r1   r2   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r+| d d d D ]}|t kr n| ||r|d7 }|dkr*| |  nqt| | d S )Nr         )Marker
nodesEqualremover   append)r   r'   Z
equalCountelementr   r   r   r?   {   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   r=      s
   z#ActiveFormattingElements.nodesEqualN)r4   r5   r6   r?   r=   r   r   r   r   r8   z   s    r8   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)openElementsr8   activeFormattingElementsZheadPointerZformPointerinsertFromTabledocumentClassdocumentr!   r   r   r   rD      s   zTreeBuilder.resetc                 C   s   t |d}|st|trtd |f}t|tsJ t| \}}t| jD ]}|r/||kr/ dS |s9|j|kr9 dS ||j|v A rC dS q$J )NrA   r
   TF)	hasattr
isinstancer   r	   tuplelistElementsMapreversedrE   rA   )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s|| jv rd S |tkr>|| jvr>|dkr,d}n|d8 }| j | }|tkr>|| jvs%	 |d7 }| j | }| }| d|j|j|jd}|| j |< || j d krgd S q?)Nr:   r   r9   TZStartTag)typer   	namespacer*   )	rF   lenr<   rE   r1   insertElementr   rS   r   )r   ientryZcloner@   r   r   r   #reconstructActiveFormattingElements   s4   

	

z/TreeBuilder.reconstructActiveFormattingElementsc                 C   s@   | j  }| j r|tkr| j  }| j r|tksd S d S d S d S r3   )rF   popr<   )r   rW   r   r   r   clearActiveFormattingElements  s   

z)TreeBuilder.clearActiveFormattingElementsc                 C   s:   | j ddd D ]}|tkr dS |j|kr|  S q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 falseNr9   F)rF   r<   r   )r   r   itemr   r   r   !elementInActiveFormattingElements  s   
z-TreeBuilder.elementInActiveFormattingElementsc                 C   s&   |  |}| j| | j| d S r3   )createElementrE   r?   rI   r(   )r   tokenr@   r   r   r   
insertRoot  s   
zTreeBuilder.insertRootc                 C   s6   |d }|d }|d }|  |||}| j| d S )Nr   publicIdsystemId)doctypeClassrI   r(   )r   r^   r   r`   ra   Zdoctyper   r   r   insertDoctype   s
   zTreeBuilder.insertDoctypec                 C   s*   |d u r	| j d }|| |d  d S )Nr9   r*   )rE   r(   commentClass)r   r^   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   rS   r*   )getrC   elementClassr   r   r^   r   rS   r@   r   r   r   r]   -  s
   
zTreeBuilder.createElementc                 C      | j S r3   )_insertFromTabler!   r   r   r   _getInsertFromTable5  s   zTreeBuilder._getInsertFromTablec                 C   s"   || _ |r| j| _dS | j| _dS )zsSwitch the function used to insert an element from the
        normal one to the misnested table one and back againN)rj   insertElementTablerU   insertElementNormal)r   r   r   r   r   _setInsertFromTable8  s   zTreeBuilder._setInsertFromTablec                 C   sb   |d }t |tsJ d| |d| j}| ||}|d |_| jd | | j| |S )Nr   zElement %s not unicoderS   r*   r9   )	rK   r   rf   rC   rg   r   rE   r(   r?   rh   r   r   r   rm   C  s   
zTreeBuilder.insertElementNormalc                 C   s`   |  |}| jd jtvr| |S |  \}}|du r"|| n||| | j| |S )z-Create an element and insert it into the treer9   N)	r]   rE   r   r   rm   getTableMisnestedNodePositionr(   r+   r?   )r   r^   r@   r   r+   r   r   r   rl   M  s   

zTreeBuilder.insertElementTablec                 C   sX   |du r	| j d }| jr| jr| j d jtvr|| dS |  \}}||| dS )zInsert text data.Nr9   )rE   rG   r   r   r,   ro   )r   r*   r   r+   r   r   r   r,   ]  s   

zTreeBuilder.insertTextc                 C   s   d}d}d}| j ddd D ]}|jdkr|} nq|r7|jr(|j}|}||fS | j | j |d  }||fS | j d }||fS )zsGet the foster parent element, and sibling to insert before
        (or None) when inserting a misnested table nodeNr9   r   r:   r   )rE   r   r   index)r   Z	lastTableZfosterParentr+   Zelmr   r   r   ro   l  s&   

z)TreeBuilder.getTableMisnestedNodePositionc                 C   s@   | j d j}|tdv r||kr| j   | | d S d S d S )Nr9   )ddZdtZlir   r   pZrpZrt)rE   r   	frozensetrY   generateImpliedEndTags)r   Zexcluder   r   r   r   rt     s   
z"TreeBuilder.generateImpliedEndTagsc                 C   ri   )zReturn the final tree)rI   r!   r   r   r   getDocument  s   zTreeBuilder.getDocumentc                 C   s   |   }| jd | |S )zReturn the final fragmentr   )fragmentClassrE   r0   )r   Zfragmentr   r   r   getFragment  s   zTreeBuilder.getFragmentc                 C   r#   )zSerialize the subtree of node in the format required by unit tests

        :arg node: the node from which to start serializing

        r$   r&   r   r   r   testSerializer  r)   zTreeBuilder.testSerializerr3   )r4   r5   r6   r7   rH   rg   rd   rb   rv   r   rD   rQ   rX   rZ   r\   r_   rc   re   r]   rk   rn   propertyrG   rm   rl   r,   ro   rt   ru   rw   rx   r   r   r   r   rB      s8    
.

	



rB   )Z
__future__r   r   r   Zsixr   Z	constantsr   r   r	   r<   rs   rM   objectr   r   r8   rB   r   r   r   r   <module>   s2    



c