o
    _c                     @   s  d Z ddlZddlmZ ddlZddlmZ ddlmZm	Z	m
Z
mZmZmZmZ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mZmZ ddlmZmZmZ ddl m!Z! e"e#Z$G dd deZ%G dd de&Z'G dd de&Z(dZ)dS )zFrame Manager module.    N)OrderedDict)SimpleNamespace)Any	AwaitableDict	GeneratorListOptionalSetUnion)EventEmitter)helper)
CDPSession)ElementHandle)NetworkError)ExecutionContextJSHandle)ElementHandleError	PageErrorTimeoutError)
merge_dictc                       sl  e Zd ZdZeddddddZded	ed
eddf fddZ	deddfddZ
deddfddZd	eddfddZeded fddZded fddZdeded fddZdededdfdd Zd!eddfd"d#Zded$eddfd%d&Zdeddfd'd(Zd)eddfd*d+Zd,eddfd-d.Zd;d/d0Zd1edefd2d3Z	d<d4ed5edefd6d7Zd=d9d:Z   Z!S )>FrameManagerzFrameManager class.ZframeattachedZframenavigatedZframedetachedZlifecycleeventZframenavigatedwithindocument)FrameAttachedFrameNavigatedFrameDetachedLifecycleEventFrameNavigatedWithinDocumentclient	frameTreepagereturnNc                    s   t    | _| _t  _d _t  _|	d fdd |	d fdd |	d fdd |	d	 fd
d |	d fdd |	d fdd |	d fdd |	d fdd |	d fdd  
| dS )zMake new frame manager.NzPage.frameAttachedc                    s     | dd| ddS )NframeId parentFrameId)_onFrameAttachedgeteventself B/usr/local/lib/python3.10/dist-packages/pyppeteer/frame_manager.py<lambda>.   s    z'FrameManager.__init__.<locals>.<lambda>zPage.frameNavigatedc                         | dS )Nframe)_onFrameNavigatedr%   r&   r(   r*   r+   r,   2       zPage.navigatedWithinDocumentc                    s     | d| dS )Nr!   url)_onFrameNavigatedWithinDocumentr%   r&   r(   r*   r+   r,   4   s    zPage.frameDetachedc                    r-   Nr!   )_onFrameDetachedr%   r&   r(   r*   r+   r,   8   r0   zPage.frameStoppedLoadingc                    r-   r3   )_onFrameStoppedLoadingr%   r&   r(   r*   r+   r,   :       zRuntime.executionContextCreatedc                    r-   )Ncontext)_onExecutionContextCreatedr%   r&   r(   r*   r+   r,   >   r6   z!Runtime.executionContextDestroyedc                    r-   )NexecutionContextId)_onExecutionContextDestroyedr%   r&   r(   r*   r+   r,   A   r6   z Runtime.executionContextsClearedc                    s      S N)_onExecutionContextsClearedr&   r(   r*   r+   r,   D   s    zPage.lifecycleEventc                    s
     | S r;   )_onLifecycleEventr&   r(   r*   r+   r,   F   s   
 )super__init___client_pager   _frames
_mainFramedict_contextIdToContexton_handleFrameTree)r)   r   r   r   	__class__r(   r+   r?   $   sD   









zFrameManager.__init__r'   c                 C   s@   | j |d }|sd S ||d |d  | tjj| d S )Nr!   loaderIdname)rB   r%   r=   emitr   Eventsr   )r)   r'   r.   r*   r*   r+   r=   J   s
   zFrameManager._onLifecycleEventr!   c                 C   s0   | j |}|s
d S |  | tjj| d S r;   )rB   r%   _onLoadingStoppedrL   r   rM   r   r)   r!   r.   r*   r*   r+   r5   Q   s
   z#FrameManager._onFrameStoppedLoadingc                 C   sV   |d }d|v r|  |d |d  | | d|vrd S |d D ]}| | q!d S )Nr.   parentIdidchildFrames)r$   r/   rG   )r)   r   r.   childr*   r*   r+   rG   X   s   
zFrameManager._handleFrameTreeFramec                 C      | j S )zReturn main frame.)rC   r(   r*   r*   r+   	mainFramee      zFrameManager.mainFramec                 C   s   t | j S )zReturn all frames.)listrB   valuesr(   r*   r*   r+   framesj   s   zFrameManager.framesc                 C   s   | j |S )z%Return :class:`Frame` of ``frameId``.)rB   r%   )r)   r!   r*   r*   r+   r.   n   s   zFrameManager.framer#   c                 C   sF   || j v rd S | j |}t| j||}|| j |< | tjj| d S r;   )rB   r%   rT   r@   rL   r   rM   r   )r)   r!   r#   parentFramer.   r*   r*   r+   r$   r   s   

zFrameManager._onFrameAttachedframePayloadc                 C   s   | d }|r| j}n
| j | dd}|s|std|r+|jD ]}| | q#| dd}|rP|rA| j|jd  ||_nt| j	d |}|| j|< || _|
| | tjj| d S )NrP   rQ   r"   zGWe either navigate top level or have old version of the navigated frame)r%   rC   rB   r   rR   _removeFramesRecursivelypop_idrT   r@   
_navigatedrL   r   rM   r   )r)   r\   ZisMainFramer.   rS   r_   r*   r*   r+   r/   z   s&   


zFrameManager._onFrameNavigatedr1   c                 C   sB   | j |}|s
d S || | tjj| | tjj| d S r;   )rB   r%   _navigatedWithinDocumentrL   r   rM   r   r   )r)   r!   r1   r.   r*   r*   r+   r2      s   
z,FrameManager._onFrameNavigatedWithinDocumentc                 C   s"   | j |}|r| | d S d S r;   )rB   r%   r]   rO   r*   r*   r+   r4      s   zFrameManager._onFrameDetachedcontextPayloadc                    s     dr d  dr d d }nd }j |}dtdtf fdd}tj ||}|j d < |r?|| d S d S )NZauxDatar!   objr    c                    s     d }|| S )NrQ   )executionContextByIdcreateJSHandle)rc   r7   rb   r)   r*   r+   _createJSHandle   s   z@FrameManager._onExecutionContextCreated.<locals>._createJSHandlerQ   )r%   rB   r   r   r   r@   rE   _addExecutionContext)r)   rb   r!   r.   rg   r7   r*   rf   r+   r8      s"   
z'FrameManager._onExecutionContextCreatedr9   c                 C   s8   | j |}|s
d S | j |= |j}|r|| d S d S r;   )rE   r%   r.   _removeExecutionContext)r)   r9   r7   r.   r*   r*   r+   r:      s   z)FrameManager._onExecutionContextDestroyedc                 C   s2   | j  D ]}|j}|r|| q| j   d S r;   )rE   rY   r.   ri   clear)r)   r7   r.   r*   r*   r+   r<      s   
z(FrameManager._onExecutionContextsCleared	contextIdc                 C   s"   | j |}|std| |S )z*Get stored ``ExecutionContext`` by ``id``.z*INTERNAL ERROR: missing context with id = )rE   r%   r   )r)   rk   r7   r*   r*   r+   rd      s   z!FrameManager.executionContextByIdr7   remoteObjectc                 C   s>   |du rt  }|ddkrt|| j|| j| S t|| j|S )z@Create JS handle associated to the context id and remote object.Nsubtypenode)rD   r%   r   r@   rA   r   )r)   r7   rl   r*   r*   r+   re      s   
zFrameManager.createJSHandler.   c                 C   sB   |j D ]}| | q|  | j|jd  | tjj	| d S r;   )
rR   r]   _detachrB   r^   r_   rL   r   rM   r   )r)   r.   rS   r*   r*   r+   r]      s
   
z%FrameManager._removeFramesRecursivelyr    Nr;   )r.   rT   r    N)"__name__
__module____qualname____doc__r   rM   r   r   r   r?   r=   strr5   rG   propertyr	   rV   r   rZ   r.   r$   rD   r/   r2   r4   r8   r:   r<   r   rd   r   re   r]   __classcell__r*   r*   rH   r+   r      s@    & 




r   c                   @   s  e Zd ZdZdeded  deddfddZd	eddfd
dZ	d	eddfddZ
d	ee ddfddZdee fddZdededefddZdddedededefddZdedee fddZdefddZd edee fd!d"Zdedededefd#d$Zdedededee fd%d&Zdedee fd'd(ZeZeZeZeZeZdefd)d*Z d+eddfd,d-Z!e"defd.d/Z#e"defd0d1Z$e"ded  fd2d3Z%e"ded  fd4d5Z&defd6d7Z'd8edefd9d:Z(d;edefd<d=Z)d;edefd>d?Z*dnded;e+d@eddfdAdBZ,deddfdCdDZ-deddfdEdFZ.dedGedee fdHdIZ/deddfdJdKZ0dndedLed;e+d@eddf
dMdNZ1	dndOe2ee3e4f d;e+ded@ede2e5dPf f
dQdRZ6dnded;e+d@eddPfdSdTZ7dndUed;e+d@eddPfdVdWZ8dnded;e+ded@eddPf
dXdYZ9	dndZed[ed;e+d@eddPf
d\d]Z:defd^d_Z;d`e+ddfdadbZ<dceddfdddeZ=dfedgeddfdhdiZ>dodjdkZ?dodldmZ@dS )prT   z_Frame class.

    Frame objects can be obtained via :attr:`pyppeteer.page.Page.mainFrame`.
    r   r[   r!   r    Nc                 C   sr   || _ || _d| _d| _|| _d | _dd | _| d  t | _	d| _
t | _t | _| jr7| jj|  d S d S )Nr"   Fc                 S      d S r;   r*   _r*   r*   r+   r,          z Frame.__init__.<locals>.<lambda>)r@   _parentFrame_url	_detachedr_   _documentPromise_contextResolveCallback_setDefaultContextset
_waitTasks	_loaderId_lifecycleEvents_childFramesadd)r)   r   r[   r!   r*   r*   r+   r?      s   

zFrame.__init__r7   c                 C   s   |j r
| | d S d S r;   Z
_isDefaultr   r)   r7   r*   r*   r+   rh        zFrame._addExecutionContextc                 C   s   |j r
| d  d S d S r;   r   r   r*   r*   r+   ri     r   zFrame._removeExecutionContextc                    sd   |d ur  | dd  _  jD ]} jj|  qd S d  _ jj  _ fdd _ d S )Nc                 S   rx   r;   r*   ry   r*   r*   r+   r,     r{   z*Frame._setDefaultContext.<locals>.<lambda>c                    s    j | S r;   )_contextPromise
set_result)_contextr(   r*   r+   r,     s    )	r   r   r@   _loopcreate_taskrerunr   create_futurer   )r)   r7   waitTaskr*   r(   r+   r     s   



zFrame._setDefaultContextc                    s   | j I dH S )zReturn execution context of this frame.

        Return :class:`~pyppeteer.execution_context.ExecutionContext`
        associated to this frame.
        N)r   r(   r*   r*   r+   executionContext  s   zFrame.executionContextpageFunctionargsc                    s8   |   I dH }|du rtd|j|g|R  I dH S )ziExecute function on this frame.

        Details see :meth:`pyppeteer.page.Page.evaluateHandle`.
        Nzthis frame has no context.)r   r   evaluateHandle)r)   r   r   r7   r*   r*   r+   r   !  s
   zFrame.evaluateHandleF)
force_exprr   c                   s>   |   I dH }|du rtd|j|g|R d|iI dH S )zhEvaluate pageFunction on this frame.

        Details see :meth:`pyppeteer.page.Page.evaluate`.
        NExecutionContext is None.r   )r   r   evaluate)r)   r   r   r   r7   r*   r*   r+   r   +  s   zFrame.evaluateselectorc                    $   |   I dH }||I dH }|S )zuGet element which matches `selector` string.

        Details see :meth:`pyppeteer.page.Page.querySelector`.
        N)	_documentquerySelectorr)   r   documentvaluer*   r*   r+   r   7     zFrame.querySelectorc                    sZ   | j r| j S |  I d H }|d u rtd|dI d H  }|| _ |d u r+td|S )NzNo context exists.r   zCould not find `document`.)r   r   r   r   	asElement)r)   r7   r   r*   r*   r+   r   @  s   zFrame._document
expressionc                    r   )zEvaluate the XPath expression.

        If there are no such elements in this frame, return an empty list.

        :arg str expression: XPath string to be evaluated.
        N)r   xpath)r)   r   r   r   r*   r*   r+   r   L  s   zFrame.xpathc                    s*   |   I dH }|j||g|R  I dH S )zExecute function on element which matches selector.

        Details see :meth:`pyppeteer.page.Page.querySelectorEval`.
        N)r   querySelectorEval)r)   r   r   r   r   r*   r*   r+   r   W  s   zFrame.querySelectorEvalc                    s.   |   I dH }|j||g|R  I dH }|S )zExecute function on all elements which matches selector.

        Details see :meth:`pyppeteer.page.Page.querySelectorAllEval`.
        N)r   JJeval)r)   r   r   r   r   r   r*   r*   r+   querySelectorAllEval`  s   zFrame.querySelectorAllEvalc                    r   )zvGet all elements which matches `selector`.

        Details see :meth:`pyppeteer.page.Page.querySelectorAll`.
        N)r   querySelectorAllr   r*   r*   r+   r   j  r   zFrame.querySelectorAllc                    s   |  d I dH S )z(Get the whole HTML contents of the page.z
() => {
  let retVal = '';
  if (document.doctype)
    retVal = new XMLSerializer().serializeToString(document.doctype);
  if (document.documentElement)
    retVal += document.documentElement.outerHTML;
  return retVal;
}
        N)r   stripr(   r*   r*   r+   content~  s   	
zFrame.contenthtmlc                    s   d}|  ||I dH  dS )zSet content to this page.zS
function(html) {
  document.open();
  document.write(html);
  document.close();
}
Nr   )r)   r   funcr*   r*   r+   
setContent  s   zFrame.setContentc                 C   s   | j ddS )zGet frame name._namer"   )__dict__r%   r(   r*   r*   r+   rK     s   z
Frame.namec                 C   rU   )zGet url of the frame.r}   r(   r*   r*   r+   r1     rW   z	Frame.urlc                 C   rU   )zcGet parent frame.

        If this frame is main frame or detached frame, return ``None``.
        )r|   r(   r*   r*   r+   r[     s   zFrame.parentFramec                 C   s
   t | jS )zGet child frames.)rX   r   r(   r*   r*   r+   rR     s   
zFrame.childFramesc                 C   rU   )zXReturn ``True`` if this frame is detached.

        Otherwise return ``False``.
        )r~   r(   r*   r*   r+   
isDetached  s   zFrame.isDetachedfilePathc                    sb   t d t|}| }W d   n1 sw   Y  |d|dd7 }| |I dH S )z&[Deprecated] Inject file to the frame.zE`injectFile` method is deprecated. Use `addScriptTag` method instead.Nz/* # sourceURL= {} */
r"   )loggerwarningopenreadformatreplacer   )r)   r   fcontentsr*   r*   r+   
injectFile  s   


zFrame.injectFileoptionsc           
   
      s~  |   I dH }|du rtdd}d}t|dtrP|d }||g}d|v r/||d  z|j| I dH  W S  tyO } z	td| d|d}~ww t|d	trt	|d	 }|
 }	W d   n1 smw   Y  |	d
|d	 dd }	||	g}d|v r||d  |j| I dH  S t|dtr||d g}d|v r||d  |j| I dH  S td)zeAdd script tag to this frame.

        Details see :meth:`pyppeteer.page.Page.addScriptTag`.
        Nr   a  
        async function addScriptUrl(url, type) {
            const script = document.createElement('script');
            script.src = url;
            if (type)
                script.type = type;
            const promise = new Promise((res, rej) => {
                script.onload = res;
                script.onerror = rej;
            });
            document.head.appendChild(script);
            await promise;
            return script;
        }a  
        function addScriptContent(content, type = 'text/javascript') {
            const script = document.createElement('script');
            script.type = type;
            script.text = content;
            let error = null;
            script.onerror = e => error = e;
            document.head.appendChild(script);
            if (error)
                throw error;
            return script;
        }r1   typezLoading script from  failedpathz//# sourceURL={}r   r"   r   <Provide an object with a `url`, `path` or `content` property)r   r   
isinstancer%   ru   appendr   r   r   r   r   r   r   
ValueError)
r)   r   r7   ZaddScriptUrlZaddScriptContentr1   r   er   r   r*   r*   r+   addScriptTag  sT   
zFrame.addScriptTagc           	   
      s*  |   I dH }|du rtdd}d}t|dtrB|d }z|||I dH  W S  tyA } z	td| d|d}~ww t|dtr|t|d }|	 }W d   n1 s_w   Y  |d	
|d d
d }|||I dH  S t|dtr|||d I dH  S td)zcAdd style tag to this frame.

        Details see :meth:`pyppeteer.page.Page.addStyleTag`.
        Nr   a  
        async function (url) {
            const link = document.createElement('link');
            link.rel = 'stylesheet';
            link.href = url;
            const promise = new Promise((res, rej) => {
                link.onload = res;
                link.onerror = rej;
            });
            document.head.appendChild(link);
            await promise;
            return link;
        }a  
        async function (content) {
            const style = document.createElement('style');
            style.type = 'text/css';
            style.appendChild(document.createTextNode(content));
            const promise = new Promise((res, rej) => {
                style.onload = res;
                style.onerror = rej;
            });
            document.head.appendChild(style);
            await promise;
            return style;
        }r1   zLoading style from r   r   z/*# sourceURL={}*/r   r"   r   r   )r   r   r   r%   ru   r   r   r   r   r   r   r   r   )	r)   r   r7   ZaddStyleUrlZaddStyleContentr1   r   r   r   r*   r*   r+   addStyleTag  sN   
zFrame.addStyleTagkwargsc                    sN   t ||}| |I dH }|std| ||I dH  | I dH  dS )zjClick element which matches ``selector``.

        Details see :meth:`pyppeteer.page.Page.click`.
        NNo node found for selector: )r   Jr   clickdispose)r)   r   r   r   handler*   r*   r+   r   >  s   
zFrame.clickc                    sF   |  |I dH }|std| | d|I dH  | I dH  dS )zjFocus element which matches ``selector``.

        Details see :meth:`pyppeteer.page.Page.focus`.
        Nr   zelement => element.focus())r   r   r   r   r)   r   r   r*   r*   r+   focusK  s   zFrame.focusc                    B   |  |I dH }|std| | I dH  | I dH  dS )ztMouse hover the element which matches ``selector``.

        Details see :meth:`pyppeteer.page.Page.hover`.
        Nr   )r   r   hoverr   r   r*   r*   r+   r   V     zFrame.hoverrY   c                    sB   |D ]}t |tstd| dt| q| |d|I dH S )zlSelect options and return selected values.

        Details see :meth:`pyppeteer.page.Page.select`.
        zValues must be string. Found z	 of type al  
(element, values) => {
    if (element.nodeName.toLowerCase() !== 'select')
        throw new Error('Element is not a <select> element.');

    const options = Array.from(element.options);
    element.value = undefined;
    for (const option of options) {
        option.selected = values.includes(option.value);
        if (option.selected && !element.multiple)
            break;
    }

    element.dispatchEvent(new Event('input', { 'bubbles': true }));
    element.dispatchEvent(new Event('change', { 'bubbles': true }));
    return options.filter(option => option.selected).map(options => options.value)
}
        N)r   ru   	TypeErrorr   r   )r)   r   rY   r   r*   r*   r+   selecta  s   

zFrame.selectc                    r   )znTap the element which matches the ``selector``.

        Details see :meth:`pyppeteer.page.Page.tap`.
        Nr   )r   r   tapr   r   r*   r*   r+   r     r   z	Frame.taptextc                    sV   t ||}| |I dH }|du rtd||||I dH  | I dH  dS )zxType ``text`` on the element which matches ``selector``.

        Details see :meth:`pyppeteer.page.Page.type`.
        NzCannot find {} on this page)r   r   r   r   r   r   )r)   r   r   r   r   r   r*   r*   r+   r     s   
z
Frame.typeselectorOrFunctionOrTimeoutWaitTaskc                 O   s   t ||}t|ttfr| jjt|d }|S t|t	s4| jj
 }|tdt	t|  |S |s;t|rE| j||g|R  S |drP| ||S | ||S )zlWait until `selectorOrFunctionOrTimeout`.

        Details see :meth:`pyppeteer.page.Page.waitFor`.
          zUnsupported target type: z//)r   r   intfloatr@   r   r   asynciosleepru   r   set_exceptionr   r   r   	is_jsfuncwaitForFunction
startswithwaitForXPathwaitForSelector)r)   r   r   r   r   futr*   r*   r+   waitFor  s.   



zFrame.waitForc                 K      t ||}| |d|S )zWait until element which matches ``selector`` appears on page.

        Details see :meth:`pyppeteer.page.Page.waitForSelector`.
        Fr   _waitForSelectorOrXPath)r)   r   r   r   r*   r*   r+   r        
zFrame.waitForSelectorr   c                 K   r   )zWait until element which matches ``xpath`` appears on page.

        Details see :meth:`pyppeteer.page.Page.waitForXPath`.
        Tr   )r)   r   r   r   r*   r*   r+   r     r   zFrame.waitForXPathc                 O   s@   t ||}|dd}|dd}t| |d||| jjg|R  S )zmWait until the function completes.

        Details see :meth:`pyppeteer.page.Page.waitForFunction`.
        timeout0u  pollingraffunction)r   r%   r   r@   r   )r)   r   r   r   r   r   r   r*   r*   r+   r     s   
zFrame.waitForFunctionselectorOrXPathisXPathc                 K   s   t ||}|dd}t|d}t|d}|s|rdnd}d|r'dnd	||r-d
nd}	d}
t| |
|	||| jj||||
S )Nr   r   visiblehiddenr   mutationz	{} "{}"{}ZXPathr   z to be hiddenr"   a  
(selectorOrXPath, isXPath, waitForVisible, waitForHidden) => {
    const node = isXPath
        ? document.evaluate(selectorOrXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue
        : document.querySelector(selectorOrXPath);
    if (!node)
        return waitForHidden;
    if (!waitForVisible && !waitForHidden)
        return node;
    const element = /** @type {Element} */ (node.nodeType === Node.TEXT_NODE ? node.parentElement : node);

    const style = window.getComputedStyle(element);
    const isVisible = style && style.visibility !== 'hidden' && hasVisibleBoundingBox();
    const success = (waitForVisible === isVisible || waitForHidden === !isVisible)
    return success ? node : null

    function hasVisibleBoundingBox() {
        const rect = element.getBoundingClientRect();
        return !!(rect.top || rect.bottom || rect.width || rect.height);
    }
}
        )r   r%   boolr   r   r@   r   )r)   r   r   r   r   r   ZwaitForVisibleZwaitForHiddenr   title	predicater*   r*   r+   r     s.   


zFrame._waitForSelectorOrXPathc                    s   |  dI dH S )zGet title of the frame.z() => document.titleNr   r(   r*   r*   r+   r     s   zFrame.titler\   c                 C   s.   | dd| _| dd| _| dd| _d S )NrK   r"   r1   )r%   r   Z_navigationURLr}   )r)   r\   r*   r*   r+   r`     s   zFrame._navigatedr1   c                 C   s
   || _ d S r;   r   )r)   r1   r*   r*   r+   ra     s   
zFrame._navigatedWithinDocumentrJ   rK   c                 C   s,   |dkr|| _ | j  d S | j| d S )Ninit)r   r   rj   r   )r)   rJ   rK   r*   r*   r+   r=     s   zFrame._onLifecycleEventc                 C   s   | j d | j d d S )NZDOMContentLoadedload)r   r   r(   r*   r*   r+   rN     s   zFrame._onLoadingStoppedc                 C   s>   | j D ]	}|td qd| _| jr| jj|  d | _d S )Nz+waitForFunction failed: frame got detached.T)r   	terminater   r~   r|   r   remove)r)   r   r*   r*   r+   ro     s   

zFrame._detachr;   rp   )Arq   rr   rs   rt   r   r	   ru   r?   r   rh   ri   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ZJxZJevalZJJr   r   r   rv   rK   r1   r[   rR   r   r   r   r   rD   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r`   ra   r=   rN   ro   r*   r*   r*   r+   rT      s    

	


	


	E<




	
	

2
rT   c                   @   sx   e Zd ZdZdedededeeef dede	j
ded	d
fddZd	efddZded	d
fddZdddZdddZd
S )r   z>WaitTask class.

    Instance of this class is awaitable.
    r.   predicateBodyr   r   r   loopr   r    Nc           	         s  t |tr|dvrtd| nt |ttfr$|dkr#td| ntd| | _| _| _| _|s>t	
|rFd| d _nd|  _| _d _d	 _d	 _|j   j  _d
tttf dd f fdd}|r j| j _ j   _d S )N)r   r   zUnknown polling: r   z(Cannot poll with non-positive interval: zUnknown polling option: zreturn (z
)(...args)zreturn Fr   r    c                    s<   t | d I d H  d _ td d|  d d S )Nr   TzWaiting for z failed: timeout zms exceeds.)r   r   _timeoutErrorr   r   )r   r)   r   r*   r+   timerH  s   
z WaitTask.__init__.<locals>.timer)r   ru   r   r   r   _frame_polling_timeoutr   r   r   _predicateBody_args	_runCount_terminatedr   r   r   r   promiser   r   _timeoutTimerr   Z_runningTask)	r)   r.   r   r   r   r   r   r   r   r*   r   r+   r?   *  s8   
 zWaitTask.__init__c                 c   s     | j E dH }t|tr||S )zMake this class **awaitable**.N)r  r   	Exception)r)   resultr*   r*   r+   	__await__S  s
   
zWaitTask.__await__errorc                 C   s(   d| _ | j s| j| |   dS )zTerminate this task.TN)r  r  doner   _cleanup)r)   r  r*   r*   r+   r   Z  s   
zWaitTask.terminatec              
      s  | j d  }| _ d}d}z%| j I dH }|du rtd|jt| j| j| jg| j	R  I dH }W n t
yF } z|}W Y d}~nd}~ww | j rNdS | jsV|| j kra|r_| I dH  dS z|sz|rz| jd|I dH rz| I dH  W dS W n ty   |dur| I dH  Y dS w t|trd|jd v rdS t|trd|jd v rdS |r| j| n| j| |   dS )zStart polling.   NzNo execution context.zs => !szExecution context was destroyedr   z%Cannot find context with specified id)r  r  r   r   r   waitForPredicatePageFunctionr  r  r  r  r
  r  r  r  r   r   r   r   r   r   r   r  )r)   ZrunCountsuccessr  r7   r   r*   r*   r+   r   a  sd   


zWaitTask.rerunc                 C   s(   | j r| js| j  | jj|  d S r;   )r  r   r	  cancelr  r   r   r(   r*   r*   r+   r    s   
zWaitTask._cleanuprp   )rq   rr   rs   rt   rT   ru   r   r   r   r   AbstractEventLoopr   r?   r   r  r
  r   r   r  r*   r*   r*   r+   r   $  s&    


)
9r   a  
async function waitForPredicatePageFunction(predicateBody, polling, timeout, ...args) {
  const predicate = new Function('...args', predicateBody);
  let timedOut = false;
  if (timeout)
    setTimeout(() => timedOut = true, timeout);
  if (polling === 'raf')
    return await pollRaf();
  if (polling === 'mutation')
    return await pollMutation();
  if (typeof polling === 'number')
    return await pollInterval(polling);

  /**
   * @return {!Promise<*>}
   */
  function pollMutation() {
    const success = predicate.apply(null, args);
    if (success)
      return Promise.resolve(success);

    let fulfill;
    const result = new Promise(x => fulfill = x);
    const observer = new MutationObserver(mutations => {
      if (timedOut) {
        observer.disconnect();
        fulfill();
      }
      const success = predicate.apply(null, args);
      if (success) {
        observer.disconnect();
        fulfill(success);
      }
    });
    observer.observe(document, {
      childList: true,
      subtree: true,
      attributes: true
    });
    return result;
  }

  /**
   * @return {!Promise<*>}
   */
  function pollRaf() {
    let fulfill;
    const result = new Promise(x => fulfill = x);
    onRaf();
    return result;

    function onRaf() {
      if (timedOut) {
        fulfill();
        return;
      }
      const success = predicate.apply(null, args);
      if (success)
        fulfill(success);
      else
        requestAnimationFrame(onRaf);
    }
  }

  /**
   * @param {number} pollInterval
   * @return {!Promise<*>}
   */
  function pollInterval(pollInterval) {
    let fulfill;
    const result = new Promise(x => fulfill = x);
    onTimeout();
    return result;

    function onTimeout() {
      if (timedOut) {
        fulfill();
        return;
      }
      const success = predicate.apply(null, args);
      if (success)
        fulfill(success);
      else
        setTimeout(onTimeout, pollInterval);
    }
  }
}
)*rt   r   collectionsr   loggingtypesr   typingr   r   r   r   r   r	   r
   r   Zpyeer   Z	pyppeteerr   Zpyppeteer.connectionr   Zpyppeteer.element_handler   Zpyppeteer.errorsr   Zpyppeteer.execution_contextr   r   r   r   r   Zpyppeteer.utilr   	getLoggerrq   r   r   objectrT   r   r  r*   r*   r*   r+   <module>   s0   (
 S    =|