Skip to content

Commit

Permalink
added element.mouse_drag method to drag element (no idea why :)) + demo
Browse files Browse the repository at this point in the history
  • Loading branch information
ultrafunkamsterdam committed Apr 30, 2024
1 parent 4ab5689 commit 2a6eb78
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 2 deletions.
98 changes: 97 additions & 1 deletion nodriver/core/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ def __getitem__(self, item):

async def save_to_dom(self):
"""
saves a screenshot of this element only
saves element to dom
:return:
:rtype:
"""
Expand All @@ -239,6 +239,7 @@ async def save_to_dom(self):
await self.update()

async def remove_from_dom(self):
"""removes the element from dom"""
await self.update() # ensure we have latest node_id
node = util.filter_recurse(
self._tree, lambda node: node.backend_node_id == self.backend_node_id
Expand Down Expand Up @@ -511,6 +512,7 @@ async def mouse_click(
button: str = "left",
buttons: typing.Optional[int] = 1,
modifiers: typing.Optional[int] = 0,
hold: bool = False,
_until_event: typing.Optional[type] = None,
):
"""native click (on element) . note: this likely does not work atm, use click() instead
Expand Down Expand Up @@ -581,6 +583,100 @@ async def mouse_move(self):
cdp.input_.dispatch_mouse_event("mouseReleased", x=center[0], y=center[1])
)

async def mouse_drag(
self,
destination: typing.Union[Element, typing.Tuple[int, int]],
relative: bool = False,
steps: int = 1,
):
"""
drag an element to another element or target coordinates. dragging of elements should be supported by the site of course
:param destination: another element where to drag to, or a tuple (x,y) of ints representing coordinate
:type destination: Element or coordinate as x,y tuple
:param relative: when True, treats coordinate as relative. for example (-100, 200) will move left 100px and down 200px
:type relative:
:param steps: move in <steps> points, this could make it look more "natural" (default 1),
but also a lot slower.
for very smooth action use 50-100
:type steps: int
:return:
:rtype:
"""
try:
start_point = (await self.get_position()).center
except AttributeError:
return
if not start_point:
logger.warning("could not calculate box model for %s", self)
return
end_point = None
if isinstance(destination, Element):
try:
end_point = (await destination.get_position()).center
except AttributeError:
return
if not end_point:
logger.warning("could not calculate box model for %s", destination)
return
elif isinstance(destination, (tuple, list)):
if relative:
end_point = (
start_point[0] + destination[0],
start_point[1] + destination[1],
)
else:
end_point = destination

await self._tab.send(
cdp.input_.dispatch_mouse_event(
"mousePressed",
x=start_point[0],
y=start_point[1],
button=cdp.input_.MouseButton("left"),
)
)

steps = 1 if (not steps or steps < 1) else steps
if steps == 1:
await self._tab.send(
cdp.input_.dispatch_mouse_event(
"mouseMoved",
x=end_point[0],
y=end_point[1],
)
)
elif steps > 1:
# probably the worst waay of calculating this. but couldn't think of a better solution today.
step_size_x = (end_point[0] - start_point[0]) / steps
step_size_y = (end_point[1] - start_point[1]) / steps
pathway = [
(start_point[0] + step_size_x * i, start_point[1] + step_size_y * i)
for i in range(steps + 1)
]

for point in pathway:
await self._tab.send(
cdp.input_.dispatch_mouse_event(
"mouseMoved",
x=point[0],
y=point[1],
)
)
await asyncio.sleep(0)

await self._tab.send(
cdp.input_.dispatch_mouse_event(
type_="mouseReleased",
x=end_point[0],
y=end_point[1],
button=cdp.input_.MouseButton("left"),
)
)

async def scroll_into_view(self):
"""scrolls element into view"""
try:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "nodriver" # Required
version = "0.28rc1" # Required
version = "0.29rc1" # Required
description = """
* Official successor of Undetected Chromedriver
* Can be made to work for for all chromium based browsers.
Expand Down

0 comments on commit 2a6eb78

Please sign in to comment.