o
    _c84                     @   s   d Z ddlZddl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 er0ddlmZ G d	d
 d
eZG dd deZG dd deZdS )zKeyboard and Mouse module.    N)AnyDictTYPE_CHECKING)
CDPSession)PyppeteerError)keyDefinitions)
merge_dict)Setc                	   @   s   e Zd ZdZdeddfddZddeded	eddfd
dZ	dede
fddZdedefddZdeddfddZdeddfddZddeded	eddfddZddeded	eddfddZdS )Keyboarda  Keyboard class provides as api for managing a virtual keyboard.

    The high level api is :meth:`type`, which takes raw characters and
    generate proper keydown, keypress/input, and keyup events on your page.

    For finer control, you can use :meth:`down`, :meth:`up`, and
    :meth:`sendCharacter` to manually fire events as if they were generated
    from a real keyboard.

    An example of holding down ``Shift`` in order to select and delete some
    text:

    .. code::

        await page.keyboard.type('Hello, World!')
        await page.keyboard.press('ArrowLeft')

        await page.keyboard.down('Shift')
        for i in ' World':
            await page.keyboard.press('ArrowLeft')
        await page.keyboard.up('Shift')

        await page.keyboard.press('Backspace')
        # Result text will end up saying 'Hello!'.

    An example of pressing ``A``:

    .. code::

        await page.keyboard.down('Shift')
        await page.keyboard.press('KeyA')
        await page.keyboard.up('Shift')
    clientreturnNc                 C   s   || _ d| _t | _d S )Nr   )_client
_modifiersset_pressedKeys)selfr    r   :/usr/local/lib/python3.10/dist-packages/pyppeteer/input.py__init__5   s   zKeyboard.__init__keyoptionskwargsc                    s   t ||}| |}|d | jv }| j|d  |  j| |d O  _|d}|du r3|d }| jd|r;dnd| j|d |d |d ||||d	 |d	 d
kd
I dH  dS )ai  Dispatch a ``keydown`` event with ``key``.

        If ``key`` is a single character and no modifier keys besides ``Shift``
        are being held down, and a ``keypress``/``input`` event will also
        generated. The ``text`` option can be specified to force an ``input``
        event to be generated.

        If ``key`` is a modifier key, like ``Shift``, ``Meta``, or ``Alt``,
        subsequent key presses will be sent with that modifier active. To
        release the modifier key, use :meth:`up` method.

        :arg str key: Name of key to press, such as ``ArrowLeft``.
        :arg dict options: Option can have ``text`` field, and if this option
            specified, generate an input event with this text.

        .. note::
            Modifier keys DO influence :meth:`down`. Holding down ``shift``
            will type the text in upper case.
        coder   textNInput.dispatchKeyEventZkeyDownZ
rawKeyDownkeyCodelocation   )
type	modifierswindowsVirtualKeyCoder   r   r   ZunmodifiedText
autoRepeatr   ZisKeypad)	r   _keyDescriptionForStringr   addr   _modifierBitgetr   send)r   r   r   r   descriptionr!   r   r   r   r   down:   s*   




zKeyboard.downc                 C   s4   |dkrdS |dkrdS |dkrdS |dkrdS d	S )
NZAlt   Control   ZMeta   ZShift   r   r   )r   r   r   r   r   r$   g   s   zKeyboard._modifierBit	keyStringc                 C   s  | j d@ }dddddd}t|}|std| d|v r%|d |d< |r2|dr2|d |d< d|v r<|d |d< |rI|d	rI|d	 |d< d
|v rS|d
 |d
< d|v r]|d |d< t|d dkrk|d |d< d|v ru|d |d< |r|dr|d |d< | j d@ rd|d< |S )Nr-    r   )r   r   r   r   r   zUnknown key: r   ZshiftKeyr   ZshiftKeyCoder   r   r)   r   Z	shiftTexti)r   r   r%   r   len)r   r.   shiftr'   Z
definitionr   r   r   r"   r   s>   


z!Keyboard._keyDescriptionForStringc              
      s|   |  |}|  j| |d  M  _|d | jv r"| j|d  | jdd| j|d |d |d |d dI dH  dS )	zyDispatch a ``keyup`` event of the ``key``.

        :arg str key: Name of key to release, such as ``ArrowLeft``.
        r   r   r   ZkeyUpr   r   )r   r   r   r    r   r   N)r"   r   r$   r   remover   r&   )r   r   r'   r   r   r   up   s   
zKeyboard.upcharc                    s   | j dd|iI dH  dS )aB  Send character into the page.

        This method dispatches a ``keypress`` and ``input`` event. This does
        not send a ``keydown`` or ``keyup`` event.

        .. note::
            Modifier keys DO NOT effect :meth:`sendCharacter`. Holding down
            ``shift`` will not type the text in upper case.
        zInput.insertTextr   N)r   r&   )r   r4   r   r   r   sendCharacter   s   
zKeyboard.sendCharacterr   c                    sn   t ||}|dd}|D ]&}|tv r | |d|iI dH  n| |I dH  |r4t|d I dH  qdS )a  Type characters into a focused element.

        This method sends ``keydown``, ``keypress``/``input``, and ``keyup``
        event for each character in the ``text``.

        To press a special key, like ``Control`` or ``ArrowDown``, use
        :meth:`press` method.

        :arg str text: Text to type into a focused element.
        :arg dict options: Options can have ``delay`` (int|float) field, which
          specifies time to wait between key presses in milliseconds. Defaults
          to 0.

        .. note::
            Modifier keys DO NOT effect :meth:`type`. Holding down ``shift``
            will not type the text in upper case.
        delayr   N  )r   r%   r   pressr5   asynciosleep)r   r   r   r   r6   r4   r   r   r   r      s   
zKeyboard.typec                    sR   t ||}| ||I dH  d|v rt|d d I dH  | |I dH  dS )a  Press ``key``.

        If ``key`` is a single character and no modifier keys besides
        ``Shift`` are being held down, a ``keypress``/``input`` event will also
        generated. The ``text`` option can be specified to force an input event
        to be generated.

        :arg str key: Name of key to press, such as ``ArrowLeft``.

        This method accepts the following options:

        * ``text`` (str): If specified, generates an input event with this
          text.
        * ``delay`` (int|float): Time to wait between ``keydown`` and
          ``keyup``. Defaults to 0.

        .. note::
            Modifier keys DO effect :meth:`press`. Holding down ``Shift`` will
            type the text in upper case.
        Nr6   r7   )r   r(   r9   r:   r3   )r   r   r   r   r   r   r   r8      s   
zKeyboard.pressN)__name__
__module____qualname____doc__r   r   strdictr   r(   intr$   r   r"   r3   r5   r   r8   r   r   r   r   r
      s     "
-+
r
   c                   @   s   e Zd ZdZdededdfddZdded	ed
ede	ddf
ddZ
dded	ed
ede	ddf
ddZdd
ede	ddfddZdd
ede	ddfddZdS )MousezMouse class.

    The :class:`Mouse` operates in main-frame CSS pixels relative to the
    top-left corner of the viewport.
    r   keyboardr   Nc                 C   s"   || _ || _d| _d| _d| _d S )Ng        none)r   	_keyboard_x_y_buttonr   r   rD   r   r   r   r      s
   
zMouse.__init__xyr   r   c           	   
      s   t ||}| j}| j}|| _|| _|dd}td|d D ]/}t|| j| ||   }t|| j| ||   }| jdd| j||| j	j
dI dH  qdS )zMove mouse cursor (dispatches a ``mousemove`` event).

        Options can accepts ``steps`` (int) field. If this ``steps`` option
        specified, Sends intermediate ``mousemove`` events. Defaults to 1.
        stepsr)   Input.dispatchMouseEventZ
mouseMoved)r   buttonrK   rL   r   N)r   rG   rH   r%   rangeroundr   r&   rI   rF   r   )	r   rK   rL   r   r   ZfromXZfromYrM   ir   r   r   move  s$   
z
Mouse.movec                    sl   t ||}| ||I dH  | |I dH  |r,|dr,t|ddd I dH  | |I dH  dS )a  Click button at (``x``, ``y``).

        Shortcut to :meth:`move`, :meth:`down`, and :meth:`up`.

        This method accepts the following options:

        * ``button`` (str): ``left``, ``right``, or ``middle``, defaults to
          ``left``.
        * ``clickCount`` (int): defaults to 1.
        * ``delay`` (int|float): Time to wait between ``mousedown`` and
          ``mouseup`` in milliseconds. Defaults to 0.
        Nr6   r   r7   )r   rS   r(   r%   r9   r:   r3   )r   rK   rL   r   r   r   r   r   click  s   
zMouse.clickc                    sT   t ||}|dd| _| jdd| j| j| j| jj|dp!ddI dH  dS )	a   Press down button (dispatches ``mousedown`` event).

        This method accepts the following options:

        * ``button`` (str): ``left``, ``right``, or ``middle``, defaults to
          ``left``.
        * ``clickCount`` (int): defaults to 1.
        rO   leftrN   ZmousePressed
clickCountr)   r   rO   rK   rL   r   rV   N)	r   r%   rI   r   r&   rG   rH   rF   r   r   r   r   r   r   r   r(   2  s   
	z
Mouse.downc                    sR   t ||}d| _| jdd|dd| j| j| jj|dp ddI d	H  d	S )
a  Release pressed button (dispatches ``mouseup`` event).

        This method accepts the following options:

        * ``button`` (str): ``left``, ``right``, or ``middle``, defaults to
          ``left``.
        * ``clickCount`` (int): defaults to 1.
        rE   rN   ZmouseReleasedrO   rU   rV   r)   rW   N)	r   rI   r   r&   r%   rG   rH   rF   r   rX   r   r   r   r3   F  s   
	
zMouse.upr;   )r<   r=   r>   r?   r   r
   r   floatrA   r   rS   rT   r(   r3   r   r   r   r   rC      s    

rC   c                   @   s<   e Zd ZdZdededdfddZded	eddfd
dZdS )TouchscreenzTouchscreen class.r   rD   r   Nc                 C   s   || _ || _dS )zMake new touchscreen object.N)r   rF   rJ   r   r   r   r   ^  s   
zTouchscreen.__init__rK   rL   c                    sZ   t |t |dg}| jdd|| jjdI dH  | jddg | jjdI dH  dS )zYTap (``x``, ``y``).

        Dispatches a ``touchstart`` and ``touchend`` event.
        )rK   rL   zInput.dispatchTouchEventZ
touchStart)r   touchPointsr   NZtouchEnd)rQ   r   r&   rF   r   )r   rK   rL   r[   r   r   r   tapc  s   zTouchscreen.tap)	r<   r=   r>   r?   r   r
   r   rY   r\   r   r   r   r   rZ   [  s    rZ   )r?   r9   typingr   r   r   Zpyppeteer.connectionr   Zpyppeteer.errorsr   Zpyppeteer.us_keyboard_layoutr   Zpyppeteer.utilr   r	   objectr
   rC   rZ   r   r   r   r   <module>   s    fd