# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_driver.marionette import Actions, errors
class CaretActions(Actions):
def __init__(self, marionette):
super(CaretActions, self).__init__(marionette)
self._reset_action_chain()
def _reset_action_chain(self):
# Release the action so that two consecutive clicks won't become a
# double-click.
self.release()
self.mouse_chain = self.sequence(
"pointer", "pointer_id", {"pointerType": "mouse"}
)
self.key_chain = self.sequence("key", "keyboard_id")
def move(self, element, x, y, duration=None):
"""Queue a pointer_move action.
:param element: an element where its top-left corner is the origin of
the coordinates.
:param x: Destination x-axis coordinate in CSS pixels.
:param y: Destination y-axis coordinate in CSS pixels.
:param duration: Number of milliseconds over which to distribute the
move. If None, remote end defaults to 0.
"""
rect = element.rect
el_x, el_y = rect["x"], rect["y"]
# Add the element's top-left corner (el_x, el_y) to make the coordinate
# relative to the viewport.
dest_x, dest_y = int(el_x + x), int(el_y + y)
self.mouse_chain.pointer_move(dest_x, dest_y, duration=duration)
return self
def click(self, element=None):
"""Queue a click action.
If an element is given, move the pointer to that element first,
otherwise click current pointer coordinates.
:param element: Optional element to click.
"""
self.mouse_chain.click(element=element)
return self
def flick(self, element, x1, y1, x2, y2, duration=200):
"""Queue a flick gesture on the target element.
:param element: The element to perform the flick gesture on. Its
top-left corner is the origin of the coordinates.
:param x1: Starting x-axis coordinate of the flick in CSS Pixels.
:param y1: Starting y-axis coordinate of the flick in CSS Pixels.
:param x2: Ending x-axis coordinate of the flick in CSS Pixels.
:param y2: Ending y-axis coordinate of the flick in CSS Pixels.
"""
self.move(element, x1, y1, duration=0)
self.mouse_chain.pointer_down()
self.move(element, x2, y2, duration=duration)
self.mouse_chain.pointer_up()
return self
def send_keys(self, keys):
"""Perform a keyDown and keyUp action for each character in `keys`.
:param keys: String of keys to perform key actions with.
"""
self.key_chain.send_keys(keys)
return self
def perform(self):
"""Perform the action chain built so far to the server side for execution
and clears the current chain of actions.
Warning: This method performs all the mouse actions before all the key
actions!
"""
self.mouse_chain.perform()
self.key_chain.perform()
self._reset_action_chain()
class SelectionManager(object):
"""Interface for manipulating the selection and carets of the element.
We call the blinking cursor (nsCaret) as cursor, and call AccessibleCaret as
caret for short.
Simple usage example:
::
element = marionette.find_element(By.ID, 'input')
sel = SelectionManager(element)
sel.move_caret_to_front()
"""
def __init__(self, element):
self.element = element
def _input_or_textarea(self):
"""Return True if element is either or