B
    "h                 @   s  d dl mZ ddlmZ d dlmZ d dlmZ ddlm	Z	 ddl
mZ ddlZ
ddlZddlZddlZejd	kZye W n ek
r   eZY nX erdd
lmZ ddlmZ eefZefZeZdd Zdd Zdd Zdd ZnDdd
l mZ ddl!mZ eefZeZdd Zdd Zdd Zdd Zdd Z"e# Z$dd Z%d&ddZ&dd Z'G d d! d!e(Z)e) Z*[)G d"d# d#e(Z+G d$d% d%e,Z-e%e- dS )'   )JQueryTranslator    )OrderedDict)
url_opener)extract_text)deepcopy)etreeN)   )	urlencode)urljoinc             C   s   t | j }dd |D S )Nc             S   s   g | ]}|j |jkr|jqS  )kindPOSITIONAL_OR_KEYWORDname).0pr   r   LC:\Users\sanjo\AppData\Local\Qlobot\Launcher\ext_packages\pyquery\pyquery.py
<listcomp>"   s    zgetargspec.<locals>.<listcomp>)inspect	signature
parametersvalues)funcargsr   r   r   
getargspec    s    r   c             C   s   | j S )N)__defaults__)r   r   r   r   getdefaultsspec%   s    r   c             C   s   | j S )N)__globals__)fr   r   r   func_globals(   s    r   c             C   s   | j S )N)__code__)r   r   r   r   	func_code+   s    r!   c             C   s   t t| jS )N)listr   r   r   )r   r   r   r   r   3   s    c             C   s   t | jS )N)r   r   defaults)r   r   r   r   r   6   s    c             C   s   | j S )N)r   )r   r   r   r   r   9   s    c             C   s   | j S )N)r!   )r   r   r   r   r!   <   s    c             C   s   t | j | S )z4decorator for methods who required a camelcase alias)_camel_case_aliasesadd__name__)r   r   r   r   with_camel_case_alias@   s    r'   c             C   s   xt D ]|}t|d}|d ddd |dd D  }t| |}tt|t||t	|}d|j
 |_t| ||d|  qW dS )	z add camelcase aliases to PyQuery_r    c             S   s   g | ]}|  qS r   )title)r   r   r   r   r   r   M   s    z,build_camel_case_aliases.<locals>.<listcomp>r   Nz-Alias for :func:`~pyquery.pyquery.PyQuery.%s`)r$   r"   splitjoingetattrtypesFunctionTyper!   r   r   r&   __doc__setattr__get__)PyQueryaliaspartsr   r   r   r   r   r   build_camel_case_aliasesI   s    
$
r6   c             C   st  t | drt | jdrd}nd}|dkr*|dkrytt|| }W n: tjk
r~   t | drj| d ttj|| }Y nX t|tj	r|
 gS |gS n|dkrtt|}nx|d	krttj|}nb|d
krddlm} t||}nB|dkr
ddlm} t||}n |dkrtjj}ntd| || }t|tkrD|S t|tj	r\|
 gS |dk	rl|gS g S dS )z/use html parser if we don't have clean xml
    read__call__parse
fromstringNseekr   xmlhtmlhtml5)html5parserZsoup)
soupparserZhtml_fragmentszNo such parser: "%s")hasattrr7   r-   r   ZXMLSyntaxErrorr;   lxmlr=   
isinstanceZ_ElementTreegetroot	lxml.htmlr?   r@   Zfragments_fromstring
ValueErrortyper"   )contextparserZcustom_parsermethresultr?   r@   r   r   r   r:   V   sF    








r:   c             G   s   | |d t | j  S )N)r!   co_argcount)r   r   r   r   r   callback   s    rM   c               @   s   e Zd Zdd ZdS )	NoDefaultc             C   s   dS )zclean representation in Sphinxz<NoDefault>r   )selfr   r   r   __repr__   s    zNoDefault.__repr__N)r&   
__module____qualname__rP   r   r   r   r   rN      s   rN   c               @   s.   e Zd ZdZeefddZdd Zdd ZdS )	FlexibleElementz property to allow a flexible apic             C   s   || _ || _|| _d S )N)pgetpsetpdel)rO   rT   rU   rV   r   r   r   __init__   s    zFlexibleElement.__init__c                s   G  fdddt }| S )Nc                   sL   e Zd ZdZ fddZe Z Z ZZ fddZ	e	Z
fddZdS )	z)FlexibleElement.__get__.<locals>._elementzOreal element to support set/get/del attr and item and js call
            stylec                s   j  f||S )N)rT   )propr   kwargs)instancerO   r   r   r8      s    z2FlexibleElement.__get__.<locals>._element.__call__c                s    j tk	r  |S t d S )N)rV   
no_defaultNotImplementedError)rX   r   )rZ   rO   r   r   __delitem__   s    
z5FlexibleElement.__get__.<locals>._element.__delitem__c                s   d j j S )Nz<flexible_element %s>)rT   r&   )rX   )rO   r   r   rP      s    z2FlexibleElement.__get__.<locals>._element.__repr__N)r&   rQ   rR   r0   r8   __getattr____getitem____setattr____setitem__r]   __delattr__rP   r   )rZ   rO   r   r   _element   s   rc   )object)rO   rZ   klassrc   r   )rZ   rO   r   r2      s    zFlexibleElement.__get__c             C   s"   | j tk	r|  || nt d S )N)rU   r[   r\   )rO   rZ   valuer   r   r   __set__   s    
zFlexibleElement.__set__N)r&   rQ   rR   r0   r[   rW   r2   rg   r   r   r   r   rS      s   rS   c               @   sB  e Zd ZdZeZdd ZdddZdd Zd	d
 Z	e
jZe
jZdd Zdd ZdddZdd Zdd Zdd Zdd Zdd Zdd Zedd Zed d! Zdd#d$Zdd%d&Zdd'd(Zdd)d*Zd+d, Zd-d. Zd/d0 Z e!dd1d2Z"d3d4 Z#e!dd5d6Z$dd7d8Z%dd9d:Z&dd;d<Z'dd=d>Z(d?d@ Z)dAdB Z*dCdD Z+dEdF Z,dGdH Z-dIdJ Z.dKdL Z/dMdN Z0edOdP Z1dQdR Z2dSdT Z3dUdV Z4e!dWdX Z5e6e4e5dYZ4e7fdZd[Z8e7fd\d]Z9e!d^d_ Z:e!d`da Z;e!dbdc Z<e!ddde Z=dfdg Z>e6e>e>dhZ>didj Z?dkdl Z@e7fdmdnZAe7fdodpZBe!ddrdsZCe7fdtduZDdvdw ZEdxdy Ze!dzd{ ZFd|d} ZGe!d~d ZHdd ZIe!dd ZJdd ZKe!dd ZLdd ZMe!dd ZNe!dd ZOe!dd ZPdd ZQdd ZRe7fddZSG dd deTZUeU ZVe!dd ZWdd ZXe!dd ZYe!dd ZZedd Z[dddZ\dS )r3   zThe main class
    c             O   s  d }g }d | _ |dd | _t|dkrvt|d trv|d ddd dkrv|d |d< t|dkrr|d |d< g }d	|kr|d	| _nt| _d
|kr|d
| _	n>| jdkr| j
dd| _	n$| jtk	r| jj	| _	n| j
dd| _	|dd | _|rd|krt|d }nbd|krh|d}d|krH|d}||f|}n
t||}| js`d| _|| _ ntd| t|| j}t|dry|  W n tk
r   Y nX nt }}t|}	|	dkr|d }n|	dkr|\}}ntdt|tr,yt|| j}W n tk
r(    Y nX nLt|| jrH|d d  }n0t|trZ|}nt|tjrp|g}nt||r|tk	r| |}
g }x$|D ]}||j|
| jd qW |}t| | d S )NrI   r   r   z://)httphttpsurl   dataparentZcss_translator)r<   T)ZxhtmlF
namespacesfilenameopenerr=   zInvalid keyword arguments %sclosez,You can't do that. Please, provide arguments)rn   )	_base_urlpoprI   lenrC   string_typesr+   _parentr[   _translator_translator_classrn   openr   rF   r:   rA   rq   	Exception
basestring	__class__r"   r   _Element	TypeError_css_to_xpathextendxpathrW   )rO   r   rY   r=   elementsrj   rp   selectorrH   lengthr   resultstagr   r   r   rW      s    















zPyQuery.__init__descendant-or-self::c             C   s   | dd}| j||S )Nz[@[)replacerw   Zcss_to_xpath)rO   r   prefixr   r   r   r     s    zPyQuery._css_to_xpathc             O   s   | d| j | j||S )Nrn   )
setdefaultrn   r|   )rO   r   rY   r   r   r   _copy  s    zPyQuery._copyc             O   sx   t |}|dkrtd|d dkr.| g S t |dkr`t|d tr`|d ds`|| f7 }| j|d| i|}|S )z&return a new PyQuery instance
        r   z$You must provide at least a selectorr)   r   <rm   )rt   rF   r   rC   ru   
startswith)rO   r   rY   r   rK   r   r   r   r8      s    

zPyQuery.__call__c             C   s.   t || jst| | d d  |d d   S )N)rC   r|   AssertionErrorr   )rO   otherr   r   r   __add__4  s    zPyQuery.__add__c             C   s&   t || jst| |dd  | S )z!Extend with anoter PyQuery objectN)rC   r|   r   _extend)rO   r   r   r   r   r   8  s    zPyQuery.extendNc             c   s8   |r| |pg }n| }x|D ]}| j || dV  qW dS )al  Iter over elements. Return PyQuery objects:

            >>> d = PyQuery('<div><span>foo</span><span>bar</span></div>')
            >>> [i.text() for i in d.items('span')]
            ['foo', 'bar']
            >>> [i.text() for i in d('span').items()]
            ['foo', 'bar']
            >>> list(d.items('a')) == list(d('a').items())
            True
        )rm   N)r   )rO   r   Zelemselemr   r   r   items>  s
    
zPyQuery.itemsc             C   s6   y| d   }W n tk
r$   Y nX tj| | S )a  Remove xhtml namespace:

            >>> doc = PyQuery(
            ...         '<html xmlns="http://www.w3.org/1999/xhtml"></html>')
            >>> doc
            [<{http://www.w3.org/1999/xhtml}html>]
            >>> doc.xhtml_to_html()
            [<html>]
        r   )getroottree
IndexErrorrB   r=   xhtml_to_html)rO   rootr   r   r   r   P  s    
zPyQuery.xhtml_to_htmlc             C   s^   y| d   }W n tk
r$   Y n6X x2|dD ]$}|jdr2|jddd |_q2W | S )zRemove all namespaces:

            >>> doc = PyQuery('<foo xmlns="http://example.com/foo"></foo>')
            >>> doc
            [<{http://example.com/foo}foo>]
            >>> doc.remove_namespaces()
            [<foo>]
        r   z{*}*{}r   )r   r   iterr   r   r+   )rO   r   elr   r   r   remove_namespacesb  s    	zPyQuery.remove_namespacesc                s$   t rtnd d fdd| D S )zxml representation of current nodes::

            >>> xml = PyQuery(
            ...   '<script><![[CDATA[ ]></script>', parser='html_fragments')
            >>> print(str(xml))
            <script>&lt;![[CDATA[ ]&gt;</script>

        Nr)   c                s   g | ]}t j| d qS ))encoding)r   tostring)r   e)r   r   r   r     s    z#PyQuery.__str__.<locals>.<listcomp>)PY3kstrr,   )rO   r   )r   r   __str__u  s    	zPyQuery.__str__c             C   s   d dd | D S )z#xml representation of current nodesr)   c             S   s   g | ]}t j|td qS ))r   )r   r   	text_type)r   r   r   r   r   r     s   z'PyQuery.__unicode__.<locals>.<listcomp>)r,   )rO   r   r   r   __unicode__  s    
zPyQuery.__unicode__c             C   s   d dd | D S )zhtml representation of current nodes::

            >>> html = PyQuery(
            ...   '<script><![[CDATA[ ]></script>', parser='html_fragments')
            >>> print(html.__html__())
            <script><![[CDATA[ ]></script>

        r)   c             S   s   g | ]}t jj|td qS ))r   )rB   r=   r   r   )r   r   r   r   r   r     s   z$PyQuery.__html__.<locals>.<listcomp>)r,   )rO   r   r   r   __html__  s    	
zPyQuery.__html__c          	   C   s   g }yvxb| D ]Z}| d}|r2dd|d p4d}| d}|rLd| pNd}|d|j||f  qW dd	| d
 S  tk
r   trt| S x2| D ]*}t	|t
r||d q|| qW t|S Y nX d S )Nclass. r)   id#z<%s%s%s>r   z, ]zutf-8)getr,   r+   appendr   AttributeErrorr   r"   rP   rC   r   encoderepr)rO   rr   cr   r   r   r   rP     s"    





zPyQuery.__repr__c             C   s$   | j tk	r| j d  S | d  S )z$return the xml root element
        r   )rv   r[   r   )rO   r   r   r   r     s    
zPyQuery.rootc             C   s   | j }|dk	r| j jjS dS )z4return the xml encoding of the root element
        N)r   Zdocinfor   )rO   r   r   r   r   r     s    zPyQuery.encodingFc       
      C   s   |dkr|}n4|  |d}g }x"|D ]}||j|| jd q$W |rN|  |rz|}g }x|D ]}	|	|kr`||	 q`W | j|| dS )z]Filters the selection set only, as opposed to also including
           descendants.
        Nzself::)rn   )rm   )r   r   r   rn   reverser   r   )
rO   r   r   r   uniquer   r   r   result_listitemr   r   r   _filter_only  s    

zPyQuery._filter_onlyc             C   s   | j |dd | D ddS )Nc             S   s    g | ]}|  d k	r|  qS )N)	getparent)r   r   r   r   r   r     s    z"PyQuery.parent.<locals>.<listcomp>T)r   )r   )rO   r   r   r   r   rm     s    zPyQuery.parentc             C   s   |  |dd | D S )Nc             S   s    g | ]}|  d k	r|  qS )N)getprevious)r   r   r   r   r   r     s    z PyQuery.prev.<locals>.<listcomp>)r   )rO   r   r   r   r   prev  s    zPyQuery.prevc             C   s   |  |dd | D S )Nc             S   s    g | ]}|  d k	r|  qS )N)getnext)r   r   r   r   r   r     s    z PyQuery.next.<locals>.<listcomp>)r   )rO   r   r   r   r   next  s    zPyQuery.nextc             c   s>   x8| D ]0}t || }x|d k	r4|V  t || }qW qW d S )N)r-   )rO   methodr   currentr   r   r   	_traverse  s
    

zPyQuery._traversec             c   sZ   xT| D ]L}g }|  }x|d k	r4|| |  }qW |  x|D ]
}|V  qDW qW d S )N)r   r   r   )rO   r   Z	this_listr   jr   r   r   _traverse_parent_topdown  s    



z PyQuery._traverse_parent_topdownc             C   s   dd |  dD S )Nc             S   s   g | ]}|qS r   r   )r   r   r   r   r   r     s    z%PyQuery._next_all.<locals>.<listcomp>r   )r   )rO   r   r   r   	_next_all  s    zPyQuery._next_allc             C   s   |  ||  S )z
        >>> h = '<span><p class="hello">Hi</p><p>Bye</p><img scr=""/></span>'
        >>> d = PyQuery(h)
        >>> d('p:last').next_all()
        [<img>]
        >>> d('p:last').nextAll()
        [<img>]
        )r   r   )rO   r   r   r   r   next_all  s    
zPyQuery.next_allc             C   s   dd |  dD S )Nc             S   s   g | ]}|qS r   r   )r   r   r   r   r   r     s    z%PyQuery._prev_all.<locals>.<listcomp>r   )r   )rO   r   r   r   	_prev_all  s    zPyQuery._prev_allc             C   s   | j ||  ddS )z
        >>> h = '<span><p class="hello">Hi</p><p>Bye</p><img scr=""/></span>'
        >>> d = PyQuery(h)
        >>> d('p:last').prev_all()
        [<p.hello>]
        >>> d('p:last').prevAll()
        [<p.hello>]
        T)r   )r   r   )rO   r   r   r   r   prev_all  s    
zPyQuery.prev_allc             C   s   |  ||  |   S )z
         >>> h = '<span><p class="hello">Hi</p><p>Bye</p><img scr=""/></span>'
         >>> d = PyQuery(h)
         >>> d('.hello').siblings()
         [<p>, <img>]
         >>> d('.hello').siblings('img')
         [<img>]

        )r   r   r   )rO   r   r   r   r   siblings  s    
zPyQuery.siblingsc             C   s   | j |dd |  D ddS )z
        >>> d = PyQuery('<span><p class="hello">Hi</p><p>Bye</p></span>')
        >>> d('p').parents()
        [<span>]
        >>> d('.hello').parents('span')
        [<span>]
        >>> d('.hello').parents('p')
        []
        c             S   s   g | ]}|qS r   r   )r   r   r   r   r   r   (  s    z#PyQuery.parents.<locals>.<listcomp>T)r   )r   r   )rO   r   r   r   r   parents  s    
zPyQuery.parentsc             C   s   dd | D }|  ||S )aG  Filter elements that are direct children of self using optional
        selector:

            >>> d = PyQuery('<span><p class="hello">Hi</p><p>Bye</p></span>')
            >>> d
            [<span>]
            >>> d.children()
            [<p.hello>, <p>]
            >>> d.children('.hello')
            [<p.hello>]
        c             S   s   g | ]}|  D ]}|qqS r   )getchildren)r   r   childr   r   r   r   8  s    z$PyQuery.children.<locals>.<listcomp>)r   )rO   r   r   r   r   r   children,  s    zPyQuery.childrenc             C   sX   g }xD| D ]<}x$|dk	r2|  ||s2| }qW |dk	r
|| q
W | j || dS )aC  
        >>> d = PyQuery(
        ...  '<div class="hello"><p>This is a '
        ...  '<strong class="hello">test</strong></p></div>')
        >>> d('strong').closest('div')
        [<div.hello>]
        >>> d('strong').closest('.hello')
        [<strong.hello>]
        >>> d('strong').closest('form')
        []
        N)rm   )r   is_r   r   )rO   r   rK   r   r   r   r   closest;  s    

zPyQuery.closestc             C   s6   g }x"| D ]}| |jd| jd q
W | j|| dS )z
        Return contents (with text nodes):

            >>> d = PyQuery('hello <b>bold</b>')
            >>> d.contents()  # doctest: +ELLIPSIS
            ['hello ', <Element b at ...>]
        zchild::text()|child::*)rn   )rm   )r   r   rn   r   )rO   r   r   r   r   r   contentsP  s
    

zPyQuery.contentsc             C   s   t |ds| || S g }tt}zHxBt| D ]6\}}t|dkrN|t|d< t|||r.|| q.W W dt|}d|kr|d= X | j|| dS dS )a  Filter elements in self using selector (string or function):

            >>> d = PyQuery('<p class="hello">Hi</p><p>Bye</p>')
            >>> d('p')
            [<p.hello>, <p>]
            >>> d('p').filter('.hello')
            [<p.hello>]
            >>> d('p').filter(lambda i: i == 1)
            [<p>]
            >>> d('p').filter(lambda i: PyQuery(this).text() == 'Hi')
            [<p.hello>]
            >>> d('p').filter(lambda i, this: PyQuery(this).text() == 'Hi')
            [<p.hello>]
        r8   r   thisN)rm   )	rA   r   r   rM   	enumeratert   r   r   r   )rO   r   r   r   ir   	f_globalsr   r   r   filter^  s    
zPyQuery.filterc                s,   t | ||  | j fdd| D | dS )zReturn elements that don't match the given selector:

            >>> d = PyQuery('<p class="hello">Hi</p><p>Bye</p><div></div>')
            >>> d('p').not_('.hello')
            [<p>]
        c                s   g | ]}| kr|qS r   r   )r   r   )excluder   r   r     s    z PyQuery.not_.<locals>.<listcomp>)rm   )setr   )rO   r   r   )r   r   not_~  s    zPyQuery.not_c             C   s   t | || S )al  Returns True if selector matches at least one current element, else
        False:

            >>> d = PyQuery('<p class="hello"><span>Hi</span></p><p>Bye</p>')
            >>> d('p').eq(0).is_('.hello')
            True

            >>> d('p').eq(0).is_('span')
            False

            >>> d('p').eq(1).is_('.hello')
            False

        ..
        )boolr   )rO   r   r   r   r   r     s    zPyQuery.is_c                sH     | fdd D }g }x|D ]}|| q(W  j| dS )a&  Find elements using selector traversing down from self:

            >>> m = '<p><span><em>Whoah!</em></span></p><p><em> there</em></p>'
            >>> d = PyQuery(m)
            >>> d('p').find('em')
            [<em>, <em>]
            >>> d('p').eq(1).find('em')
            [<em>]
        c                s*   g | ]"}|  D ]}|j jd qqS ))rn   )r   r   rn   )r   r   r   )rO   r   r   r   r     s   z PyQuery.find.<locals>.<listcomp>)rm   )r   r   r   )rO   r   r   r   r   r   )rO   r   r   find  s    


zPyQuery.findc             C   s4   y| | }W n t k
r$   g }Y nX | j|| dS )a.  Return PyQuery of only the element with the provided index::

            >>> d = PyQuery('<p class="hello">Hi</p><p>Bye</p><div></div>')
            >>> d('p').eq(0)
            [<p.hello>]
            >>> d('p').eq(1)
            [<p>]
            >>> d('p').eq(2)
            []

        ..
        )rm   )r   r   )rO   indexr   r   r   r   eq  s
    
z
PyQuery.eqc             C   sV   z8x2t | D ]&\}}|t|d< t|||dkrP qW W dt|}d|krP|d= X | S )z!apply func on each nodes
        r   FN)r   r   rM   )rO   r   r   elementr   r   r   r   each  s    
zPyQuery.eachc             C   s   g }zZxTt | D ]H\}}|t|d< t|||}|dk	rt|tsN|| q|| qW W dt|}d|krv|d= X | j|| dS )a;  Returns a new PyQuery after transforming current items with func.

        func should take two arguments - 'index' and 'element'.  Elements can
        also be referred to as 'this' inside of func::

            >>> d = PyQuery('<p class="hello">Hi there</p><p>Bye</p><br />')
            >>> d('p').map(lambda i, e: PyQuery(e).text())
            ['Hi there', 'Bye']

            >>> d('p').map(lambda i, e: len(PyQuery(this).text()))
            [8, 3]

            >>> d('p').map(lambda i, e: PyQuery(this).text().split())
            ['Hi', 'there', 'Bye']

        r   N)rm   )r   r   rM   rC   r"   r   r   r   )rO   r   r   r   r   rK   r   r   r   r   map  s    
zPyQuery.mapc             C   s   t | S )N)rt   )rO   r   r   r   r     s    zPyQuery.lengthc             C   s   t | S )N)rt   )rO   r   r   r   size  s    zPyQuery.sizec             C   s   | j S )a  Break out of a level of traversal and return to the parent level.

            >>> m = '<p><span><em>Whoah!</em></span></p><p><em> there</em></p>'
            >>> d = PyQuery(m)
            >>> d('p').eq(1).find('em').end().end()
            [<p>, <p>]
        )rv   )rO   r   r   r   end  s    zPyQuery.endc             O   s$  ddd}t  }}t|}|dkr8|d }|||}n^|dkrV|\}}|||}n@|ri }x6| D ]\}}|||||< qhW ntd||f | sdS t|trxv| D ]&}	x | D ]\}
}|	|
| qW qW nF|t kr| d |S |dkr| |S x| D ]}	|	|| q
W | S )	z Attributes manipulation
        r   for)class_Zfor_r   r   rk   zInvalid arguments %s %sN)	r[   rt   r   r   rF   rC   dictr   remove_attr)rO   r   rY   mappingattrrf   r   kvr   keyr   r   r   r     s6    





zPyQuery.attrc          	   C   s4   x.| D ]&}y|j |= W q tk
r*   Y qX qW | S )zRemove an attribute::

            >>> d = PyQuery('<div id="myid"></div>')
            >>> d.remove_attr('id')
            [<div>]
            >>> d.removeAttr('id')
            [<div>]

        ..
        )attribKeyError)rO   r   r   r   r   r   r   +  s    

zPyQuery.remove_attr)rT   rV   c             C   s   |  d|S )z"set/get height of element
        height)r   )rO   rf   r   r   r   r   C  s    zPyQuery.heightc             C   s   |  d|S )z!set/get width of element
        width)r   )rO   rf   r   r   r   r   H  s    zPyQuery.widthc             C   s   |  d| S )zReturn True if element has class::

            >>> d = PyQuery('<div class="myclass"></div>')
            >>> d.has_class('myclass')
            True
            >>> d.hasClass('myclass')
            True

        ..
        z.%s)r   )rO   r   r   r   r   	has_classM  s    zPyQuery.has_classc                sV   xP| D ]H}| d}|dp d     fdd|D 7  |dd  qW | S )zAdd a css class to elements::

            >>> d = PyQuery('<div></div>')
            >>> d.add_class('myclass')
            [<div.myclass>]
            >>> d.addClass('myclass')
            [<div.myclass>]

        ..
        r   r   r)   c                s   g | ]}| kr|qS r   r   )r   r   )classesr   r   r   j  s    z%PyQuery.add_class.<locals>.<listcomp>)r+   r   r   r,   )rO   rf   r   r   r   )r   r   	add_class[  s    

zPyQuery.add_classc             C   s~   xx| D ]p}| d}t|dp"d  }|| |dg d|}| r`|d| q|dr|d| qW | S )zRemove a css class to elements::

            >>> d = PyQuery('<div class="myclass"></div>')
            >>> d.remove_class('myclass')
            [<div>]
            >>> d.removeClass('myclass')
            [<div>]

        ..
        r   r   r)   )r+   r   r   difference_updater,   strip)rO   rf   r   r   r   r   r   r   remove_classn  s    




zPyQuery.remove_classc                s~   xx| D ]p}| d}|dp d    fdd|D } fdd|D fdd D   |7  |dd  qW | S )zToggle a css class to elements

            >>> d = PyQuery('<div></div>')
            >>> d.toggle_class('myclass')
            [<div.myclass>]
            >>> d.toggleClass('myclass')
            [<div>]

        r   r   r)   c                s   g | ]}| kr|qS r   r   )r   r   )r   r   r   r     s    z(PyQuery.toggle_class.<locals>.<listcomp>c                s   g | ]}| kr|qS r   r   )r   r   )r   r   r   r     s    c                s   g | ]}| kr|qS r   r   )r   r   )values_to_delr   r   r     s    )r+   r   r   r,   )rO   rf   r   r   Zvalues_to_addr   )r   r   r   toggle_class  s    

zPyQuery.toggle_classc                sV  t   }t|}|dkr"|d  n,|dkr4|\ }n|r>| ntd||f t trx| D ]~}dd   D fdd|dpd	d
D }x2  D ]&\}}|	dd}|
d||f  qW |dd| q^W npt|trR 	dd xV| D ]N} fdd|dpd	d
D }|
d |f  |dd| q W | S )z$css attributes manipulation
        r   r   rk   zInvalid arguments %s %sc             S   s   g | ]}|  d dqS )r(   -)r   r   )r   r   r   r   r   r     s   zPyQuery.css.<locals>.<listcomp>c                s2   g | ]*}|  r|d d    kr|  qS ):r   )r   r+   )r   r   )stripped_keysr   r   r     s   styler)   ;r(   r   z%s: %sz; c                s6   g | ].}|  r|d d      ks|  qS )r   r   )r   r+   )r   r   )r   r   r   r     s   )r[   rt   rF   rC   r   keysr   r+   r   r   r   r   r,   r{   )rO   r   rY   rf   r   r   r   r   r   )r   r   r   css  s6    






zPyQuery.css)rT   rU   c             C   s   |  ddS )zRemove display:none to elements style:

            >>> print(PyQuery('<div style="display:none;"/>').hide())
            <div style="display: none"/>

        displaynone)r   )rO   r   r   r   hide  s    zPyQuery.hidec             C   s   |  ddS )zAdd display:block to elements style:

            >>> print(PyQuery('<div />').show())
            <div style="display: block"/>

        r   block)r   )rO   r   r   r   show  s    zPyQuery.showc                sH    fdd} fdd}|t kr6t rD| d S n| |  S dS )a  Set the attribute value::

            >>> d = PyQuery('<input />')
            >>> d.val('Youhou')
            [<input>]

        Get the attribute value::

            >>> d.val()
            'Youhou'

        Set the selected values for a `select` element with the `multiple`
        attribute::

            >>> d = PyQuery('''
            ...             <select multiple>
            ...                 <option value="you"><option value="hou">
            ...             </select>
            ...             ''')
            >>> d.val(['you', 'hou'])
            [<select>]

        Get the selected values for a `select` element with the `multiple`
        attribute::

            >>> d.val()
            ['you', 'hou']

        c                s   | j dkr |  S | j dkrd| jkrP | d}t| fddS  | d}|rl|dS  | d	dS nZ d
r | d}|d krdS |S n.| j dkr܈ | d}|r|ddS dS  | dpdS )Ntextareaselectmultiplezoption[selected]c                s     |dS )Nrf   )r   r   )r(   o)rO   r   r   <lambda>      z1PyQuery.val.<locals>._get_value.<locals>.<lambda>zoption[selected]:lastrf   optionz:checkbox,:radiooninput
r)   )	r   r   r=   r   r"   r   r   r   r   )r   selectedZselected_optionval)rO   r   r   
_get_value  s(    





zPyQuery.val.<locals>._get_valuec                s   x| D ]  j dkrJtts$g fdd} d| qttr^d j dkrz  q d qW d S )Nr  c                sH     |}|dkr:|dd djkrDd d = n
|d d S )Nrf   r  r  )r   r   r   Z
removeAttr)r(   r   pq)rO   r   rf   r   r   _make_option_selected   s    

z>PyQuery.val.<locals>._set_value.<locals>._make_option_selectedr  ,r  rf   )r   rC   r"   r   r   r,   textr   )r  rf   r  )rO   )r   rf   r   
_set_value  s    





zPyQuery.val.<locals>._set_valuer   N)r[   rt   )rO   rf   r  r  r   )rO   r   r    s     
zPyQuery.valc       	         s  |t krd| sdS | d }| }|s*|jS |jp2d}d krDt d< |d fdd|D 7 }|S t|| jrzt|}n&t|tr|}n|sd}ntt	|x^| D ]V}x| D ]}|
| qW td| d | jd }| }|r|| |j|_qW | S )	ak  Get or set the html representation of sub nodes.

        Get the text value::

            >>> d = PyQuery('<div><span>toto</span></div>')
            >>> print(d.html())
            <span>toto</span>

        Extra args are passed to ``lxml.etree.tostring``::

            >>> d = PyQuery('<div><span></span></div>')
            >>> print(d.html())
            <span/>
            >>> print(d.html(method='html'))
            <span></span>

        Set the text value::

            >>> d.html('<span>Youhou !</span>')
            [<div>]
            >>> print(d)
            <div><span>Youhou !</span></div>
        Nr   r)   r   c                s   g | ]}t j|f qS r   )r   r   )r   r   )rY   r   r   r   ]  s   z PyQuery.html.<locals>.<listcomp>z<root>z</root>)r[   r   r  r   r,   rC   r|   r{   rF   rG   remover:   rI   r   )	rO   rf   rY   r   r   r=   Znew_htmlr   r   r   )rY   r   r=   ;  s>    





zPyQuery.htmlr=   c             C   s4   | sdS | d }|j r$t|}d|_ tj|t|dS )a  Get the html representation of the first selected element::

            >>> d = PyQuery('<div><span class="red">toto</span> rocks</div>')
            >>> print(d('span'))
            <span class="red">toto</span> rocks
            >>> print(d('span').outer_html())
            <span class="red">toto</span>
            >>> print(d('span').outerHtml())
            <span class="red">toto</span>

            >>> S = PyQuery('<p>Only <b>me</b> & myself</p>')
            >>> print(S('b').outer_html())
            <b>me</b>

        ..
        Nr   r)   )r   r   )tailr   r   r   r   )rO   r   Ze0r   r   r   
outer_htmlv  s    zPyQuery.outer_htmlc                s^   |t kr*sdS d fddD S x.D ]&}x| D ]}|| q>W ||_q0W S )a  Get or set the text representation of sub nodes.

        Get the text value::

            >>> doc = PyQuery('<div><span>toto</span><span>tata</span></div>')
            >>> print(doc.text())
            tototata
            >>> doc = PyQuery('''<div><span>toto</span>
            ...               <span>tata</span></div>''')
            >>> print(doc.text())
            toto tata

        Get the text value, without squashing newlines::

            >>> doc = PyQuery('''<div><span>toto</span>
            ...               <span>tata</span></div>''')
            >>> print(doc.text(squash_space=False))
            toto
            tata

        Set the text value::

            >>> doc.text('Youhou !')
            [<div>]
            >>> print(doc)
            <div>Youhou !</div>

        r)   r   c             3   s2   | ]*}|j d kr| n
t|f V  qdS )r  N)r   r   r=   r   )r   r   )rY   rO   r   r   	<genexpr>  s   zPyQuery.text.<locals>.<genexpr>)r[   r,   r   r  r  )rO   rf   rY   r   r   r   )rY   rO   r   r    s    


zPyQuery.textc             C   s   t |tr$td| d | jd }n4t |tjr<| |}nt |trL|}ntd| t	|drvt |j
trv|j
}nd}||fS )Nz<root>z</root>r   z0Value must be string, PyQuery or Element. Got %rr  r)   )rC   r{   r:   rI   r   r}   r   r3   r~   rA   r  )rO   rf   r   	root_textr   r   r   	_get_root  s    


zPyQuery._get_rootc             C   s   |  |\}}x|t| D ]p\}}t|dkrP|d }|js@d|_| j|7  _n|js\d|_| j|7  _|dkr~tt|}|| qW | S )z#append value to each nodes
        r   r)   )r  r   rt   r  r  r   r"   r   )rO   rf   r   r  r   r   Z
last_childr   r   r   r     s    zPyQuery.appendc             C   s   | |  | S )zappend nodes to value
        )r   )rO   rf   r   r   r   	append_to  s    
zPyQuery.append_toc             C   s   |  |\}}x|t| D ]p\}}|js,d|_t|dkrL|j|d _||_n||j |_|dkrltt|}||dd< |dt| }qW | S )zprepend value to nodes
        r)   r   r  N)r  r   r  rt   r  r   r"   )rO   rf   r   r  r   r   r   r   r   prepend  s    zPyQuery.prependc             C   s   | |  | S )zprepend nodes to value
        )r  )rO   rf   r   r   r   
prepend_to  s    
zPyQuery.prepend_toc             C   s   |  |\}}xtt| D ]h\}}|js,d|_| j|7  _|dkrNtt|}| }||d }||||< ||t| }qW | S )zadd value after nodes
        r)   r   r   )r  r   r  r   r"   r   r   rt   )rO   rf   r   r  r   r   rm   r   r   r   r   after  s    zPyQuery.afterc             C   s   | |  | S )z!insert nodes after value
        )r  )rO   rf   r   r   r   insert_after  s    
zPyQuery.insert_afterc       	      C   s   |  |\}}xt| D ]\}}| }|dk	rL|js<d|_| j|7  _n"| }|js`d|_| j|7  _|dkrtt|}| }||}||||< ||t	| }qW | S )z"insert value before nodes
        Nr)   r   )
r  r   r   r  r   r  r   r"   r   rt   )	rO   rf   r   r  r   r   Zpreviousrm   r   r   r   r   before  s$    
zPyQuery.beforec             C   s   | |  | S )z"insert nodes before value
        )r  )rO   rf   r   r   r   insert_before3  s    
zPyQuery.insert_beforec       	      C   s   t |tstt|d }g }x| D ]}t|}| sH|t| n(dd | D }|d }|t| || | }|dk	r$x.| D ]"}||kr|	| |
| P qW q$W || dd< | S )a  A string of HTML that will be created on the fly and wrapped around
        each target:

            >>> d = PyQuery('<span>youhou</span>')
            >>> d.wrap('<div></div>')
            [<div>]
            >>> print(d)
            <div><span>youhou</span></div>

        r   c             S   s   g | ]}|qS r   r   )r   r   r   r   r   r   N  s    z PyQuery.wrap.<locals>.<listcomp>r  N)rC   r{   r   r:   r   r   r   iterchildrenr   Zaddnextr  )	rO   rf   Znodesr   wrapperchildsr   rm   tr   r   r   wrap:  s(    




zPyQuery.wrapc             C   s   | s| S t |tstt|d }t|}| s8|}ndd | D }|d }d}| d  }|dkrnt}x*| D ]"}|	t| | |k	rtd}qtW |tk	r|rdd | D }t
|t
| krx| D ]}|| qW |	| |g| dd< | S )	a  Wrap all the elements in the matched set into a single wrapper
        element::

            >>> d = PyQuery('<div><span>Hey</span><span>you !</span></div>')
            >>> print(d('span').wrap_all('<div id="wrapper"></div>'))
            <div id="wrapper"><span>Hey</span><span>you !</span></div>

            >>> d = PyQuery('<div><span>Hey</span><span>you !</span></div>')
            >>> print(d('span').wrapAll('<div id="wrapper"></div>'))
            <div id="wrapper"><span>Hey</span><span>you !</span></div>

        ..
        r   c             S   s   g | ]}|qS r   r   )r   r   r   r   r   r   u  s    z$PyQuery.wrap_all.<locals>.<listcomp>r  TNFc             S   s   g | ]}|qS r   r   )r   r   r   r   r   r     s    )rC   r{   r   r:   r   r   r!  r   r[   r   rt   r  )rO   rf   r"  r   r#  Zreplace_childsrm   r   r   r   r   wrap_all]  s2    


zPyQuery.wrap_allc             C   s   t |trt|}t|drfxt| D ]:\}}| |||||jpHd  | }|	| q&W n:x8| D ]0}| |||jpd  | }|	| qlW | S )a$  replace nodes by value:

            >>> doc = PyQuery("<html><div /></html>")
            >>> node = PyQuery("<span />")
            >>> child = doc.find('div')
            >>> child.replace_with(node)
            [<div>]
            >>> print(doc)
            <html><span/></html>

        r8   r)   )
rC   r3   r   rA   r   r   r  r  r   r  )rO   rf   r   r   rm   r   r   r   r   replace_with  s    



zPyQuery.replace_withc             C   s&   | j tkrtd|  ||  | S )zreplace nodes by expr
        z6replaceAll can only be used with an object with parent)rv   r[   rF   r'  )rO   exprr   r   r   replace_all  s
    
zPyQuery.replace_allc             C   s   t dd | D S )zreturn a copy of nodes
        c             S   s   g | ]}t |qS r   )r   )r   r   r   r   r   r     s    z!PyQuery.clone.<locals>.<listcomp>)r3   )rO   r   r   r   clone  s    zPyQuery.clonec             C   s$   x| D ]}d|_ g |dd< qW | S )zremove nodes content
        N)r  )rO   r   r   r   r   empty  s    
zPyQuery.emptyc             C   s   |t krx| D ]v}| }|dk	r|jrz| }|dkrZ|jsDd|_| jd|j 7  _n |jsfd|_| jd|j 7  _|| qW n| || }|  | S )a@  Remove nodes:

             >>> h = (
             ... '<div>Maybe <em>she</em> does <strong>NOT</strong> know</div>'
             ... )
             >>> d = PyQuery(h)
             >>> d('strong').remove()
             [<strong>]
             >>> print(d)
             <div>Maybe <em>she</em> does   know</div>
        Nr)   r   )r[   r   r  r   r  r  r   )rO   r(  r   rm   r   r   r   r   r   r    s"    
zPyQuery.removec               @   s   e Zd ZdZdd ZdS )z
PyQuery.Fna  Hook for defining custom function (like the jQuery.fn):

        .. sourcecode:: python

         >>> fn = lambda: this.map(lambda i, el: PyQuery(this).outerHtml())
         >>> PyQuery.fn.listOuterHtml = fn
         >>> S = PyQuery(
         ...   '<ol>   <li>Coffee</li>   <li>Tea</li>   <li>Milk</li>   </ol>')
         >>> S('li').listOuterHtml()
         ['<li>Coffee</li>', '<li>Tea</li>', '<li>Milk</li>']

        c                s"    fdd}||_ tt|| d S )Nc                s   | t  d<  ||S )Nr   )r   )rO   r   rY   )r   r   r   fn  s    z"PyQuery.Fn.__setattr__.<locals>.fn)r&   r1   r3   )rO   r   r   r,  r   )r   r   r`     s    zPyQuery.Fn.__setattr__N)r&   rQ   rR   r0   r`   r   r   r   r   Fn  s   r-  c             C   s   t tdd |  S )a  Serialize form elements as an array of dictionaries, whose structure
        mirrors that produced by the jQuery API. Notably, it does not handle the
        deprecated `keygen` form element.

            >>> d = PyQuery('<form><input name="order" value="spam"></form>')
            >>> d.serialize_array() == [{'name': 'order', 'value': 'spam'}]
            True
            >>> d.serializeArray() == [{'name': 'order', 'value': 'spam'}]
            True
        c             S   s   | d | d dS )Nr   r   )r   rf   r   )r   r   r   r   r    r  z)PyQuery.serialize_array.<locals>.<lambda>)r"   r   serialize_pairs)rO   r   r   r   serialize_array  s    zPyQuery.serialize_arrayc             C   s   t |  ddS )aJ  Serialize form elements as a URL-encoded string.

            >>> h = (
            ... '<form><input name="order" value="spam">'
            ... '<input name="order2" value="baked beans"></form>'
            ... )
            >>> d = PyQuery(h)
            >>> d.serialize()
            'order=spam&order2=baked%20beans'
        +z%20)r
   r.  r   )rO   r   r   r   	serialize  s    zPyQuery.serializec       	         sH  dddddg}|  g  x|  D ]}|d jdkrz|d}|rj|  |j } |d	||f  q |d
 q"|d jdkr |d q" | q"W d}|dtdd |7 } 	|  fdd} 	| g }x\ D ]T|  
 }t|tr$|tfdd| q|jd |ddf qW |S )aQ  Serialize form elements as an array of 2-tuples conventional for
        typical URL-parsing operations in Python.

            >>> d = PyQuery('<form><input name="order" value="spam"></form>')
            >>> d.serialize_pairs()
            [('order', 'spam')]
            >>> d.serializePairs()
            [('order', 'spam')]
        submitbuttonimageresetfiler   formr   z)#%s :not([form]):input, [form="%s"]:inputz:not([form]):inputZfieldsetz:inputz[name]:enabled:not(button)r)   c             S   s   d|  S )Nz:not([type="%s"])r   )sr   r   r   r  A  r  z)PyQuery.serialize_pairs.<locals>.<lambda>c                s"     |}|d o |d S )Nz:checkbox:not(:checked)z:radio:not(:checked))r   r   )r(   r   )controlsr   r   _filter_out_uncheckedE  s    
z6PyQuery.serialize_pairs.<locals>._filter_out_uncheckedc                s    j d | ddfS )Nr   r
  z
)r   r   )r   )fieldr   r   r  Z  r  r   r
  z
)r   r   r   r   r   rD   r   r,   r   r   r  rC   r"   r   r   r   )	rO   Z_submitter_typesr   Zform_idr   r   r:  retr  r   )r9  r;  r   r.    s<    







 zPyQuery.serialize_pairsc             C   s`   t  }xT|  D ]H\}}||kr*|||< qt|| tsJ|| |g||< q|| | qW |S )ay  Serialize form elements as an ordered dictionary. Multiple values
        corresponding to the same input name are concatenated into one list.

            >>> d = PyQuery('''<form>
            ...             <input name="order" value="spam">
            ...             <input name="order" value="eggs">
            ...             <input name="order2" value="ham">
            ...             </form>''')
            >>> d.serialize_dict()
            OrderedDict([('order', ['spam', 'eggs']), ('order2', 'ham')])
            >>> d.serializeDict()
            OrderedDict([('order', ['spam', 'eggs']), ('order2', 'ham')])
        )r   r.  rC   r"   r   )rO   r<  r   r  r   r   r   serialize_dicta  s    
zPyQuery.serialize_dictc             C   s&   | j dk	r| j S | jtk	r"| jjS dS )zJReturn the url of current html document or None if not available.
        N)rr   rv   r[   base_url)rO   r   r   r   r>  z  s    

zPyQuery.base_urlc                s    dkrj   dkrtd fdd}d|d d|d d|d	 d
|d	 d|d	 d|d S )z!Make all links absolute.
        Nz]You need a base URL to make your linksabsolute. It can be provided by the base_url parameter.c                s    fdd}|S )Nc                sN   |   d krd S t fdddD r4d S | t  S )Nc             3   s   | ]}  |V  qd S )N)r   )r   Zschema)
attr_valuer   r   r    s   zIPyQuery.make_links_absolute.<locals>.repl.<locals>.rep.<locals>.<genexpr>)ztel:zcallto:zsms:)r   anyr   r   )r   r   )r   r>  rO   )r?  r   rep  s    

z6PyQuery.make_links_absolute.<locals>.repl.<locals>.repr   )r   rA  )r>  rO   )r   r   repl  s    z)PyQuery.make_links_absolute.<locals>.replahreflinkscriptsrcimgZiframer7  action)r>  rF   r   )rO   r>  rB  r   )r>  rO   r   make_links_absolute  s    zPyQuery.make_links_absolute)r   )N)FF)N)N)N)N)N)N)N)N)N)r=   )N)]r&   rQ   rR   r0   r   rx   rW   r   r   r8   r"   r   _appendr   r   r   r   r   r   r   r   r   rP   propertyr   r   r   rm   r   r   r   r   r   r'   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rS   r[   r   r   r   r   r   r   r   r   r   r  r=   r  r  r  r  r  r  r  r  r  r   r%  r&  r'  r)  r*  r+  r  rd   r-  r,  r/  r1  r.  r=  r>  rJ  r   r   r   r   r3      s   `









 !$'	_;0#1
 C	r3   )NN).Zcssselectpatchr   collectionsr   Zopenersr   r  r   copyr   rB   r   rE   r   r.   sysversion_infor   unicode	NameErrorr   urllib.parser
   r   bytesr{   ru   r   r   r   r   r!   urlliburlparser'   r   r$   r6   r:   rM   rd   rN   r[   rS   r"   r3   r   r   r   r   <module>   sn   



-!            