o
    Xh0h(>                     @   s  d Z ddlmZ ddlmZ ddlmZmZmZ dZed Z	e
edfe
ee	d	fhB dfe
ee	d
fe	dfhB dfe
e	dfe	dfgdfe
e	dfe	dfgdfdZe
dZG dd deZG dd dZG dd deZG dd deZG dd deZG dd deZG dd dZdS ) Tree builder.    )copy)ElementTree   )
namespacesscoping_elementstable_insert_mode_elementsNhtmlFbuttonolultableoptgroupoptionT)Nr
   listr   select)dddtlir   r   prprtc                   @      e Zd Zdd ZdS )ActiveFormattingElementsc                 C   sv   d}|t ur3| ddd D ]%}|t u r n|j|jko |j|jk}|r'|d7 }|dkr2| |  nqt| | dS )z#Append node to the end of the list.r   Nr      )Marker
name_tuple
attributesremover   append)selfnodeequal_countelementnodes_equal r&   K/var/www/html/rh/venv/lib/python3.10/site-packages/tinyhtml5/treebuilder.pyr       s   

zActiveFormattingElements.appendN)__name__
__module____qualname__r    r&   r&   r&   r'   r          r   c                   @   s   e Z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
ee	e
Zdd Zdd Zdd Zdd ZdddZdd Zdd ZdS )ElementNc                 C   sT   || _ || _t| ||| _|d u rt| j f| _n| j| j f| _g | _d | _	d S N)
name	namespacer   r,   _get_etree_tag_element_htmlr   	_childrenparentr!   r.   r/   r&   r&   r'   __init__-   s   
zElement.__init__c                 C   s   |d u r|S d| d| S )N{}r&   r5   r&   r&   r'   r0   :   s   zElement._get_etree_tagc                 C   s   | j jS r-   )r1   attribr!   r&   r&   r'   _get_attributes=   s   zElement._get_attributesc                 C   s\   | j j}|  |r*| D ]\}}t|tr#d|d  d|d  n|}|||< qd S d S )Nr7      r8   r   )r1   r9   clearitems
isinstancetuple)r!   r   element_attributeskeyvaluer.   r&   r&   r'   _set_attributes@   s   &
zElement._set_attributesc                 C      | j S r-   )r3   r:   r&   r&   r'   _get_childrenM      zElement._get_childrenc                 C   s*   | j d d = g | _|D ]}| | qd S r-   )r1   r3   insert_child)r!   rC   r$   r&   r&   r'   _set_childrenP   s
   zElement._set_childrenc                 C   s   t | jjp	t| jS )z>Return True if the node has children or text, False otherwise.)boolr1   textlenr:   r&   r&   r'   has_contentZ   s   zElement.has_contentc                 C   s$   | j | | j|j | |_dS )z+Insert node as a child of the current node.N)r3   r    r1   r4   r!   r"   r&   r&   r'   append_child^      
zElement.append_childc                 C   s,   t | j|j}| j||j | |_dS )zInsert node as a child of the current node, before reference.

        Raise ValueError if reference is not a child of the current node.

        N)r   r1   indexinsertr4   )r!   r"   	referencerQ   r&   r&   r'   insert_befored   s   
zElement.insert_beforec                 C   s$   | j | | j|j d|_dS )z2Remove node from the children of the current node.N)r3   r   r1   r4   rN   r&   r&   r'   remove_childn   rP   zElement.remove_childc                 C   s   t | js| jjsd| j_| j j|7  _dS |du r3| jd js'd| jd _| jd  j|7  _dS t| j}||j}|dkr`| j|d  jsRd| j|d  _| j|d   j|7  _dS | jjshd| j_| j j|7  _dS )zInsert data as text in the current node.

        Text is positioned before the start of node insert_before or to the end
        of the node's text.

        If insert_before is a node, insert the text before this node.

         Nr   r   r   )rL   r1   rK   tailr   rQ   )r!   rK   rT   childrenrQ   r&   r&   r'   insert_textt   s"   
	
zElement.insert_textc                 C   s.   t | | j| j}| jjrt| jj|j_|S )zReturn a shallow copy of the current node.

        The node has the same name and attributes, but no parent or children.

        )typer.   r/   r1   r9   r   )r!   r$   r&   r&   r'   clone   s   zElement.clonec                 C   sz   |j r|j d j j| jj7  _n|jjsd|j_| jjdur)|j j| jj7  _d| j_| j D ]}|| q0g | _ dS )zMove all the children of the current node to parent.

        This is needed so that trees that don't store text as nodes move the
        text in the correct way.

        r   rV   N)rX   r1   rW   rK   rO   )r!   r4   childr&   r&   r'   reparent_children   s   

zElement.reparent_childrenr-   )r(   r)   r*   r6   r0   r;   rD   propertyr   rF   rI   rX   rM   rO   rT   rU   rY   r[   r]   r&   r&   r&   r'   r,   ,   s     




r,   c                   @   r   )Commentc                 C   s   t || _d | _g | _d S r-   )r   r_   r1   r4   r3   )r!   datar&   r&   r'   r6      s   
zComment.__init__Nr(   r)   r*   r6   r&   r&   r&   r'   r_      r+   r_   c                   @   r   )DocumentTypec                 C   s@   t | d || j_| jd| | jd| || _|| _d S )Nz
<!DOCTYPE>publicIdsystemId)r,   r6   r1   rK   set	public_id	system_id)r!   r.   rf   rg   r&   r&   r'   r6      s   
zDocumentType.__init__Nra   r&   r&   r&   r'   rb      r+   rb   c                   @   r   )Documentc                 C      t | d d S )NDOCUMENT_ROOTr,   r6   r:   r&   r&   r'   r6         zDocument.__init__Nra   r&   r&   r&   r'   rh      r+   rh   c                   @   r   )DocumentFragmentc                 C   ri   )NDOCUMENT_FRAGMENTrk   r:   r&   r&   r'   r6      rl   zDocumentFragment.__init__Nra   r&   r&   r&   r'   rm      r+   rm   c                   @   s   e 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 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&d'Zd(d) ZdS ),TreeBuilderr   c                 C   s   |rd| _ nd| _ |   dS )zeCreate a TreeBuilder.

        If namespace_html_elements is True, namespace HTML elements.

        zhttp://www.w3.org/1999/xhtmlN)default_namespacereset)r!   namespace_html_elementsr&   r&   r'   r6      s   zTreeBuilder.__init__c                 C   s,   g | _ t | _d | _d | _d| _t | _d S )NF)open_elementsr   active_formatting_elementshead_elementform_elementinsert_from_tablerh   documentr:   r&   r&   r'   rq      s   zTreeBuilder.resetNc                 C   s   t |d}|st|trt|f}t|tsJ t| \}}t| jD ]}|r-||kr- dS |s7|j|kr7 dS ||j|v A rA dS q"J )Nr   TF)	hasattrr?   strr2   r@   _list_elementsreversedrs   r   )r!   targetvariant
exact_nodelist_elementsinvertr"   r&   r&   r'   element_in_scope   s   

zTreeBuilder.element_in_scopec                 C   s   | j sd S t| j d }| j | }|tu s|| jv rd S |tur>|| jvr>|dkr,d}n|d8 }| j | }|tur>|| jvs%	 |d7 }| j | }| }| d|j|j|jd}|| j |< || j d krgd S q?)Nr   r   r   TStartTag)rZ   r.   r/   r`   )	rt   rL   r   rs   r[   insert_elementr.   r/   r   )r!   ientryr[   r$   r&   r&   r'   &reconstruct_active_formatting_elements   s6   

	

z2TreeBuilder.reconstruct_active_formatting_elementsc                 C   s@   | j  }| j r|tur| j  }| j r|tusd S d S d S d S r-   )rt   popr   )r!   r   r&   r&   r'    clear_active_formatting_elements/  s   

z,TreeBuilder.clear_active_formatting_elementsc                 C   s:   | j ddd D ]}|tu r dS |j|kr|  S qdS )zFind name between end of active formatting elements and last marker.

        If an element with this name exists, return it. Else return False.

        Nr   F)rt   r   r.   )r!   r.   itemr&   r&   r'   %element_in_active_formatting_elements4  s   
z1TreeBuilder.element_in_active_formatting_elementsc                 C   s&   |  |}| j| | j| d S r-   )create_elementrs   r    rx   rO   )r!   tokenr$   r&   r&   r'   insert_rootC  s   
zTreeBuilder.insert_rootc                 C   s4   |d }|d }|d }t |||}| j| d S )Nr.   rc   rd   )rb   rx   rO   )r!   r   r.   rf   rg   doctyper&   r&   r'   insert_doctypeH  s
   zTreeBuilder.insert_doctypec                 C   s   | t|d  d S )Nr`   )rO   r_   )r!   r   r4   r&   r&   r'   insert_commentP  s   zTreeBuilder.insert_commentc                 C   s.   |d }| d| j}t||}|d |_|S )z/Create an element but don't insert it anywhere.r.   r/   r`   )getrp   r,   r   r!   r   r.   r/   r$   r&   r&   r'   r   S  s
   

zTreeBuilder.create_elementc                 C   rE   r-   )_insert_from_tabler:   r&   r&   r'   _get_insert_from_table[  rG   z"TreeBuilder._get_insert_from_tablec                 C   s"   || _ |r| j| _dS | j| _dS )z.Switch the function used to insert an element.N)r   insert_element_tabler   insert_element_normal)r!   rC   r&   r&   r'   _set_insert_from_table^  s   z"TreeBuilder._set_insert_from_tablec                 C   sd   |d }t |tsJ d| d|d| j}t||}|d |_| jd | | j| |S )Nr.   zElement z not unicoder/   r`   r   )	r?   rz   r   rp   r,   r   rs   rO   r    r   r&   r&   r'   r   h  s   

z!TreeBuilder.insert_element_normalc                 C   s`   |  |}| jd jtvr| |S |  \}}|du r"|| n||| | j| |S )z.Create an element and insert it into the tree.r   N)	r   rs   r.   r   r   !get_table_misnested_node_positionrO   rT   r    )r!   r   r$   r4   rT   r&   r&   r'   r   r  s   

z TreeBuilder.insert_element_tablec                 C   sV   |du r	| j d }| jo| j d jtv }|r$|  \}}||| dS || dS )zInsert text data.Nr   )rs   rw   r.   r   r   rY   )r!   r`   r4   in_tablerT   r&   r&   r'   rY     s   
zTreeBuilder.insert_textc                 C   s   d}d}d}| j ddd D ]}|jdkr|} nq|r9|jr(|j}|}||fS | j |d }| j | }||fS | j d }||fS )zAGet foster parent element and sibling (or None) to insert before.Nr   r   r   r   )rs   r.   r4   rQ   )r!   
last_tablefoster_parentrT   r$   rQ   r&   r&   r'   r     s$   


z-TreeBuilder.get_table_misnested_node_positionc                 C   s<   | j d j}|tv r||kr| j   | | d S d S d S )Nr   )rs   r.   _implied_end_tagsr   generate_implied_end_tags)r!   excluder.   r&   r&   r'   r     s
   
z%TreeBuilder.generate_implied_end_tagsFc                 C   s4   |r| j jS | j j| jdu rdS d| j dS )zReturn the final tree.Nr	   r7   z}html)rx   r1   findrp   )r!   	full_treer&   r&   r'   get_document  s   zTreeBuilder.get_documentc                 C   s   t  }| jd | |jS )zReturn the final fragment.r   )rm   rs   r]   r1   )r!   fragmentr&   r&   r'   get_fragment  s   zTreeBuilder.get_fragmentr-   )F)r(   r)   r*   __doc__r6   rq   r   r   r   r   r   r   r   r   r   r   r^   rw   r   r   rY   r   r   r   r   r&   r&   r&   r'   ro      s,    
0




ro   )r   r   	xml.etreer   	constantsr   r   r   r   r2   	frozensetr{   r   r   r   r,   r_   rb   rh   rm   ro   r&   r&   r&   r'   <module>   s*    
 	
