修复监听start()没清空问题;动作链增加input()

This commit is contained in:
g1879 2023-12-06 23:30:34 +08:00
parent 5ff303130d
commit cee5af6d7e
7 changed files with 165 additions and 71 deletions

View File

@ -3,7 +3,6 @@
@Author : g1879
@Contact : g1879@qq.com
"""
from typing import List, Tuple, Dict
class Keys:
@ -339,10 +338,10 @@ modifierBit = {'\ue00a': 1,
'\ue008': 8}
def keys_to_typing(value) -> Tuple[int, str]:
def keys_to_typing(value):
"""把要输入的内容连成字符串,去掉其中 ctrl 等键。
返回的modifier表示是否有按下组合键"""
typing: List[str] = []
typing = []
modifier = 0
for val in value:
if val in ('\ue009', '\ue008', '\ue00a', '\ue03d'):
@ -359,7 +358,7 @@ def keys_to_typing(value) -> Tuple[int, str]:
return modifier, ''.join(typing)
def keyDescriptionForString(_modifiers: int, keyString: str) -> Dict: # noqa: C901
def keyDescriptionForString(_modifiers, keyString): # noqa: C901
shift = _modifiers & 8
description = {'key': '',
'keyCode': 0,
@ -367,7 +366,7 @@ def keyDescriptionForString(_modifiers: int, keyString: str) -> Dict: # noqa: C
'text': '',
'location': 0}
definition: Dict = keyDefinitions.get(keyString) # type: ignore
definition = keyDefinitions.get(keyString) # type: ignore
if not definition:
raise ValueError(f'未知按键:{keyString}')
@ -399,3 +398,49 @@ def keyDescriptionForString(_modifiers: int, keyString: str) -> Dict: # noqa: C
description['text'] = ''
return description
def send_key(page, modifier, key):
"""发送一个字,在键盘中的字符触发按键,其它直接发送文本"""
if key not in keyDefinitions:
page.run_cdp('Input.insertText', text=key)
else:
description = keyDescriptionForString(modifier, key)
text = description['text']
data = {'type': 'keyDown' if text else 'rawKeyDown',
'modifiers': modifier,
'windowsVirtualKeyCode': description['keyCode'],
'code': description['code'],
'key': description['key'],
'text': text,
'autoRepeat': False,
'unmodifiedText': text,
'location': description['location'],
'isKeypad': description['location'] == 3}
page.run_cdp('Input.dispatchKeyEvent', **data)
data['type'] = 'keyUp'
page.run_cdp('Input.dispatchKeyEvent', **data)
def input_text_or_keys(page, text_or_keys):
"""输入文本也可输入组合键组合键用tuple形式输入
:param page: ChromiumBase对象
:param text_or_keys: 文本值或按键组合
:return: self
"""
if not isinstance(text_or_keys, (tuple, list)):
text_or_keys = (str(text_or_keys),)
modifier, text_or_keys = keys_to_typing(text_or_keys)
if modifier != 0: # 包含修饰符
for key in text_or_keys:
send_key(page, modifier, key)
return
if text_or_keys.endswith(('\n', '\ue007')):
page.run_cdp('Input.insertText', text=text_or_keys[:-1])
send_key(page, modifier, '\n')
else:
page.run_cdp('Input.insertText', text=text_or_keys)

View File

@ -0,0 +1,97 @@
# -*- coding:utf-8 -*-
"""
@Author : g1879
@Contact : g1879@qq.com
"""
from typing import Tuple, Dict, Union, Any
from .._pages.chromium_base import ChromiumBase
class Keys:
"""特殊按键"""
NULL: str
CANCEL: str
HELP: str
BACKSPACE: str
BACK_SPACE: str
TAB: str
CLEAR: str
RETURN: str
ENTER: str
SHIFT: str
LEFT_SHIFT: str
CONTROL: str
CTRL: str
LEFT_CONTROL: str
ALT: str
LEFT_ALT: str
PAUSE: str
ESCAPE: str
SPACE: str
PAGE_UP: str
PAGE_DOWN: str
END: str
HOME: str
LEFT: str
ARROW_LEFT: str
UP: str
ARROW_UP: str
RIGHT: str
ARROW_RIGHT: str
DOWN: str
ARROW_DOWN: str
INSERT: str
DELETE: str
DEL: str
SEMICOLON: str
EQUALS: str
NUMPAD0: str
NUMPAD1: str
NUMPAD2: str
NUMPAD3: str
NUMPAD4: str
NUMPAD5: str
NUMPAD6: str
NUMPAD7: str
NUMPAD8: str
NUMPAD9: str
MULTIPLY: str
ADD: str
SUBTRACT: str
DECIMAL: str
DIVIDE: str
F1: str
F2: str
F3: str
F4: str
F5: str
F6: str
F7: str
F8: str
F9: str
F10: str
F11: str
F12: str
META: str
COMMAND: str
keyDefinitions: dict = ...
modifierBit: dict = ...
def keys_to_typing(value: Union[str, int, list, tuple]) -> Tuple[int, str]: ...
def keyDescriptionForString(_modifiers: int, keyString: str) -> Dict: ...
def send_key(page: ChromiumBase, modifier: int, key: str) -> None: ...
def input_text_or_keys(page: ChromiumBase, text_or_keys: Any) -> None: ...

View File

@ -11,7 +11,7 @@ from time import perf_counter, sleep
from .none_element import NoneElement
from .session_element import make_session_ele
from .._base.base import DrissionElement, BaseElement
from .._commons.keys import keys_to_typing, keyDescriptionForString, keyDefinitions
from .._commons.keys import input_text_or_keys
from .._commons.locator import get_loc
from .._commons.settings import Settings
from .._commons.tools import get_usable_path
@ -605,21 +605,7 @@ class ChromiumElement(DrissionElement):
else:
self._input_focus()
# ------------处理字符-------------
if not isinstance(vals, (tuple, list)):
vals = (str(vals),)
modifier, vals = keys_to_typing(vals)
if modifier != 0: # 包含修饰符
for key in vals:
send_key(self, modifier, key)
return
if vals.endswith(('\n', '\ue007')):
self.page.run_cdp('Input.insertText', text=vals[:-1])
send_key(self, modifier, '\n')
else:
self.page.run_cdp('Input.insertText', text=vals)
input_text_or_keys(self.page, vals)
def clear(self, by_js=False):
"""清空元素文本
@ -1388,40 +1374,6 @@ def convert_argument(arg):
return {'unserializableValue': '-Infinity'}
def send_enter(ele):
"""发送回车"""
data = {'type': 'keyDown', 'modifiers': 0, 'windowsVirtualKeyCode': 13, 'code': 'Enter', 'key': 'Enter',
'text': '\r', 'autoRepeat': False, 'unmodifiedText': '\r', 'location': 0, 'isKeypad': False}
ele.page.run_cdp('Input.dispatchKeyEvent', **data)
data['type'] = 'keyUp'
ele.page.run_cdp('Input.dispatchKeyEvent', **data)
def send_key(ele, modifier, key):
"""发送一个字,在键盘中的字符触发按键,其它直接发送文本"""
if key not in keyDefinitions:
ele.page.run_cdp('Input.insertText', text=key)
else:
description = keyDescriptionForString(modifier, key)
text = description['text']
data = {'type': 'keyDown' if text else 'rawKeyDown',
'modifiers': modifier,
'windowsVirtualKeyCode': description['keyCode'],
'code': description['code'],
'key': description['key'],
'text': text,
'autoRepeat': False,
'unmodifiedText': text,
'location': description['location'],
'isKeypad': description['location'] == 3}
ele.page.run_cdp('Input.dispatchKeyEvent', **data)
data['type'] = 'keyUp'
ele.page.run_cdp('Input.dispatchKeyEvent', **data)
class Pseudo(object):
def __init__(self, ele):
"""

View File

@ -308,12 +308,6 @@ def parse_js_result(page: ChromiumBase, ele: ChromiumElement, result: dict): ...
def convert_argument(arg: Any) -> dict: ...
def send_enter(ele: ChromiumElement) -> None: ...
def send_key(ele: ChromiumElement, modifier: int, key: str) -> None: ...
class Pseudo(object):
def __init__(self, ele: ChromiumElement):
self._ele: ChromiumElement = ...

View File

@ -5,7 +5,7 @@
"""
from time import sleep, perf_counter
from .._commons.keys import modifierBit, keyDescriptionForString
from .._commons.keys import modifierBit, keyDescriptionForString, input_text_or_keys
from .._commons.web import location_in_viewport
@ -267,7 +267,7 @@ class Actions:
return self
def type(self, text):
"""输入文本
"""用模拟键盘按键方式输入文本,可输入字符串,只能输入键盘上有的字符
:param text: 要输入的文本特殊字符和多个文本可用list或tuple传入
:return: self
"""
@ -278,6 +278,14 @@ class Actions:
self.key_up(character)
return self
def input(self, text_or_keys):
"""输入文本也可输入组合键组合键用tuple形式输入
:param text_or_keys: 文本值或按键组合
:return: self
"""
input_text_or_keys(self.page, text_or_keys)
return self
def wait(self, second):
"""等待若干秒"""
sleep(second)

View File

@ -3,7 +3,7 @@
@Author : g1879
@Contact : g1879@qq.com
"""
from typing import Union, Tuple
from typing import Union, Tuple, Any
from .._base.chromium_driver import ChromiumDriver
from .._elements.chromium_element import ChromiumElement
@ -66,6 +66,8 @@ class Actions:
def type(self, text: Union[str, list, tuple]) -> Actions: ...
def input(self, text_or_keys: Any) -> Actions: ...
def wait(self, second: float) -> Actions: ...
def _get_key_data(self, key: str, action: str) -> dict: ...

View File

@ -77,18 +77,14 @@ class Listener(object):
"""
if targets or method:
self.set_targets(targets, is_regex, method)
self.clear()
if self.listening:
return
self._driver = ChromiumDriver(self._target_id, 'page', self._address)
self._driver.run('Network.enable')
self.listening = True
self._request_ids = {}
self._extra_info_ids = {}
self._caught = Queue(maxsize=0)
self._running_requests = 0
self._set_callback()
def wait(self, count=1, timeout=None, fit_count=True):
@ -181,7 +177,7 @@ class Listener(object):
"""清空结果"""
self._request_ids = {}
self._extra_info_ids = {}
self._caught.queue.clear()
self._caught = Queue(maxsize=0)
self._running_requests = 0
def wait_silent(self, timeout=None):