3
(hj6                 @   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buttonolultableoptgroupoptionT)Nr   listr   selectc               @   s^   e 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 )Nodec             C   s(   || _ d| _d| _i | _g | _g | _dS )a6  Node representing an item in the tree.
        name - The tag name associated with the node
        parent - The parent of the current node (or None for the document node)
        value - The value of the current node (applies to text nodes and
        comments
        attributes - a dict holding name, value pairs for attributes of the node
        childNodes - a list of child nodes of the current node. This must
        include all elements but not necessarily other node types
        _flags - A list of miscellaneous flags that can be set on the node
        N)nameparentvalue
attributes
childNodes_flags)selfr    r   @/tmp/pip-install-q3hcpn_q/html5lib/html5lib/treebuilders/base.py__init__   s    zNode.__init__c             C   s:   dj dd | j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   attributesStrr   r   r   __str__*   s
    
zNode.__str__c             C   s
   d| j  S )Nz<%s>)r   )r   r   r   r   __repr__3   s    zNode.__repr__c             C   s   t dS )z3Insert node as a child of the current node
        N)NotImplementedError)r   noder   r   r   appendChild6   s    zNode.appendChildNc             C   s   t dS )zInsert data as text in the current node, positioned before the
        start of node insertBefore or to the end of the node's text.
        N)r&   )r   datainsertBeforer   r   r   
insertText;   s    zNode.insertTextc             C   s   t dS )zInsert 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 nodeN)r&   )r   r'   refNoder   r   r   r*   A   s    zNode.insertBeforec             C   s   t dS )z:Remove node from the children of the current node
        N)r&   )r   r'   r   r   r   removeChildG   s    zNode.removeChildc             C   s$   x| j D ]}|j| 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
        N)r   r(   )r   	newParentchildr   r   r   reparentChildrenL   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   	cloneNodeV   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   
hasContent\   s    zNode.hasContent)N)__name__
__module____qualname__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rVxH| d d d D ]6}|t kr*P | j||r>|d7 }|dkr| j| P qW tj| | d S )Nr         )Marker
nodesEqualremover   append)r   r'   
equalCountelementr   r   r   r=   c   s    
zActiveFormattingElements.appendc             C   s$   |j |j ksdS |j|jks dS dS )NFT)	nameTupler   )r   node1node2r   r   r   r;   p   s
    z#ActiveFormattingElements.nodesEqualN)r3   r4   r5   r=   r;   r   r   r   r   r6   b   s   r6   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 | _ | j  d S )Nzhttp://www.w3.org/1999/xhtml)defaultNamespacereset)r   namespaceHTMLElementsr   r   r   r      s    zTreeBuilder.__init__c             C   s.   g | _ t | _d | _d | _d| _| j | _d S )NF)openElementsr6   activeFormattingElementsheadPointerformPointerinsertFromTabledocumentClassdocument)r   r   r   r   rE      s    zTreeBuilder.resetc             C   s   t |d}|s2t|tr$td |f}t|ts2tt| \}}xHt| jD ]:}|r^||kr^dS | rr|j	|krrdS ||j	|kA rJdS qJW dstd S )Nr@   r
   TF)
hasattr
isinstancer   r	   tupleAssertionErrorlistElementsMapreversedrG   r@   )r   targetvariant	exactNode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 | }|j }| jd|j|j|jd}|| j |< || j d krrP qrW d S )Nr7   r   StartTag)typer   	namespacer)   r9   r9   )	rH   lenr:   rG   r1   insertElementr   r\   r   )r   ientrycloner?   r   r   r   #reconstructActiveFormattingElements   s.    


z/TreeBuilder.reconstructActiveFormattingElementsc             C   s,   | j j }x| j r&|tkr&| j j }qW d S )N)rH   popr:   )r   r`   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 falseNr7   Fr9   )rH   r:   r   )r   r   itemr   r   r   !elementInActiveFormattingElements   s    
z-TreeBuilder.elementInActiveFormattingElementsc             C   s&   | j |}| jj| | jj| d S )N)createElementrG   r=   rM   r(   )r   tokenr?   r   r   r   
insertRoot   s    
zTreeBuilder.insertRootc             C   s6   |d }|d }|d }| j |||}| jj| d S )Nr   publicIdsystemId)doctypeClassrM   r(   )r   rh   r   rj   rk   doctyper   r   r   insertDoctype  s
    zTreeBuilder.insertDoctypec             C   s*   |d kr| j d }|j| j|d  d S )Nr7   r)   r9   )rG   r(   commentClass)r   rh   r   r   r   r   insertComment	  s    
zTreeBuilder.insertCommentc             C   s0   |d }|j d| j}| j||}|d |_|S )z.Create an element but don't insert it anywherer   r\   r)   )getrD   elementClassr   )r   rh   r   r\   r?   r   r   r   rg     s
    
zTreeBuilder.createElementc             C   s   | j S )N)_insertFromTable)r   r   r   r   _getInsertFromTable  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)rs   insertElementTabler^   insertElementNormal)r   r   r   r   r   _setInsertFromTable  s    
zTreeBuilder._setInsertFromTablec             C   sb   |d }t |tstd| |jd| j}| j||}|d |_| jd j| | jj	| |S )Nr   zElement %s not unicoder\   r)   r7   r9   )
rO   r   rQ   rq   rD   rr   r   rG   r(   r=   )r   rh   r   r\   r?   r   r   r   rv   $  s    
zTreeBuilder.insertElementNormalc             C   s`   | j |}| jd jtkr$| j|S | j \}}|dkrD|j| n|j|| | jj| |S )z-Create an element and insert it into the treer7   Nr9   )	rg   rG   r   r   rv   getTableMisnestedNodePositionr(   r*   r=   )r   rh   r?   r   r*   r   r   r   ru   .  s    

zTreeBuilder.insertElementTablec             C   sX   |dkr| j d }| j s0| jr<| j d jtkr<|j| n| j \}}|j|| dS )zInsert text data.Nr7   r9   r9   )rG   rK   r   r   r+   rx   )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 j|d  }n
| j d }||fS )zsGet the foster parent element, and sibling to insert before
        (or None) when inserting a misnested table nodeNr7   r   r   r9   )rG   r   r   index)r   	lastTablefosterParentr*   elmr   r   r   rx   M  s    

z)TreeBuilder.getTableMisnestedNodePositionc          
   C   s8   | j d
 j}|tdkr4||kr4| j j  | j| d S )Nr7   dddtlir   r   prprtr9   )r}   r~   r   r   r   r   r   r   )rG   r   	frozensetrc   generateImpliedEndTags)r   excluder   r   r   r   r   g  s
    
z"TreeBuilder.generateImpliedEndTagsc             C   s   | j S )zReturn the final tree)rM   )r   r   r   r   getDocumentq  s    zTreeBuilder.getDocumentc             C   s   | j  }| jd j| |S )zReturn the final fragmentr   )fragmentClassrG   r0   )r   fragmentr   r   r   getFragmentu  s    zTreeBuilder.getFragmentc             C   s   t dS )zzSerialize the subtree of node in the format required by unit tests
        node - the node from which to start serializingN)r&   )r   r'   r   r   r   testSerializer|  s    zTreeBuilder.testSerializer)N)N)N)N)r3   r4   r5   __doc__rL   rr   ro   rl   r   r   rE   rY   rb   rd   rf   ri   rn   rp   rg   rt   rw   propertyrK   rv   ru   r+   rx   r   r   r   r   r   r   r   r   rC   z   s6   
.
	




rC   )
__future__r   r   r   sixr   	constantsr   r   r	   r:   r   setrR   objectr   r   r6   rC   r   r   r   r   <module>   s   
K