const InputDevice = require('./InputDevice')
const Element = require('../Element')
/**
* Class for Pointer objects.
* When a Pointer object is passed to the {@link Action} constructor:
* var actions = new Actions(new Actions.Pointer('bigMouse'))
*
* the action's `tick` will have the following methods (assuming that the Pointer's ID
* is `mouse`):
*
* * {@link Pointer#Up action.tick.bigMouseUp()}
* * {@link Pointer#Down action.tick.bigMouseDown()}
* * {@link Pointer#Move action.tick.bigMouseMove()}
* * {@link Pointer#Cancel action.tick.bigMouseCancel()}
*
* Note: input device objects are only ever used in {@link Actions}
* @extends InputDevice
* @example
* var mouse = new Actions.Pointer('mouse', Pointer.Type.MOUSE)
* var touch1 = new Actions.Pointer('touch1', Pointer.Type.TOUCH)
* var touch2 = new Actions.Pointer('touch2', Pointer.Type.TOUCH)
* var actions = new Actions(mouse, touch1, touch2)
* actions.tick.mouseDown().touch1Down().touch2Down()
*/
class Pointer extends InputDevice {
/**
* Each device is associated a unique ID
* like `mouse`, `touch`, `pen`.
* @param {string} id The unique ID of the device
* @param {string} pointerType It can be `Pointer.Type.MOUSE`, `Pointer.Type.PEN`
* or `Pointer.Type.TOUCH`
*
*/
constructor (id, pointerType) {
super(id)
this.pointerType = pointerType || Pointer.Type.MOUSE
this.type = 'pointer'
}
/**
* The types of pointer types, used to create the right type of pointer.
* E.g. `Pointer.Type.MOUSE`, `Pointer.Type.PEN` or `Pointer.Type.TOUCH`,
*
* It actually returns:
*
* {
* MOUSE: 'mouse',
* PEN: 'pen',
* TOUCH: 'touch'
* }
*/
static get Type () {
return {
MOUSE: 'mouse',
PEN: 'pen',
TOUCH: 'touch'
}
}
/**
* The button types on a pointer.
*
* It actually returns:
*
* {
* LEFT: 0,
* MIDDLE: 1,
* RIGHT: 2
* }
*/
static get Button () {
return {
LEFT: 0,
MIDDLE: 1,
RIGHT: 2
}
}
/**
* The types of origins, used in `Move()` commands. See {@link Actions} on how to use
* this constant.
* E.g. `Pointer.Origin.VIEWPORT` or `Pointer.Origin.POINTER`
*
* It actually returns:
*
* {
* VIEWPORT: 'viewport',
* POINTER: 'pointer'
* }
*/
static get Origin () {
return {
VIEWPORT: 'viewport',
POINTER: 'pointer'
}
}
_tickMethods () {
return {
/**
* Move the pointer to a specified `origin` location, using `x` and `y` and offset, and taking `duration` milliseconds
*
* This method will be added to the action's `tick` property. **prefixed** with the Pointer's ID.
*
* @param {Object} params Instructions on where to move the pointer
* @param {Element|string} params.origin=Pointer.Origin.VIEWPORT Where to move the pointer to. It can be an {@link Element} object,
* or Pointer.Origin.VIEWPORT or Pointer.Origin.POINTER
* @param {number} params.x The x offset, from params.origin.
* @param {number} params.y The y offset, from params.origin.
* @param {number} params.duration How long the operation will take, in milliseconds
*
* @example
*
* // Defining a pointer device called "cucumber", and passing it
* // to the actions constructor
* var actions = new Actions( new Actions.Pointer('bigMouse'))
* // the `cucumberMove` method is now available in the tick property
* actions.tick.bigMouseMove({ x: 400, y: 400 })
*
* @memberof Pointer#
*/
Move: (args) => {
// Work out origin, defaulting to VIEWPORT.
// If it's an element, it will be seriaslised as a webdriver object
// w3c: for Chrome, we still have the ELEMENT key
// In any case, it MUST be an element, VIEWPORT or POINTER
var origin
if (!args.origin) {
origin = Pointer.Origin.VIEWPORT
} else {
if (args.origin instanceof Element) {
origin = {
'element-6066-11e4-a52e-4f735466cecf': args.origin.id,
ELEMENT: args.origin.id
}
} else {
origin = args.origin
if (origin !== Pointer.Origin.VIEWPORT &&
origin !== Pointer.Origin.POINTER) {
throw new Error('When using move(), origin must be an element, Pointer.Origin.VIEWPORT or Pointer.Origin.POINTER')
} else {
}
}
}
return {
type: 'pointerMove',
duration: args.duration || 0,
origin,
x: args.x || 0,
y: args.y || 0
}
},
/**
* Press a pointer button
*
* This method will be added to the action's `tick` property. **prefixed** with the Pointer's ID.
*
* @param {number} button=Pointer.Button.LEFT The button to press. It can be `Pointer.Button.LEFT` (0),
* `Pointer.Button.MIDDLE` (1) or `Pointer.Button.RIGHT` (2)
*
* @example
* var actions = new Actions( new Actions.Pointer('bigMouse'))
* actions.tick.bigMouseDown()
* actions.tick.bigMouseDown(Pointer.Button.RIGHT)
*
* @memberof Pointer#
*/
Down: (button = 0) => {
return {
type: 'pointerDown',
button
}
},
/** Release a pointer button
*
* This method will be added to the action's `tick` property. **prefixed** with the Pointer's ID.
*
* @param {number} button=Pointer.Button.LEFT The button to let go
*
* @example
* var actions = new Actions( new Actions.Pointer('bigMouse'))
* actions.tick.bigMouseUp()
* actions.tick.bigMouseUp(Pointer.Button.RIGHT)
*
* @memberof Pointer#
*/
Up: (button = 0) => {
return {
type: 'pointerUp',
button
}
},
/**
* Cancels the pointer
*
* This method will be added to the action's `tick` property. **prefixed** with the Pointer's ID.
* @example
* var bigMouse = new Actions.Pointer('bigMouse')
*
* // This will take 4 seconds. NOTE: there is no await before actions.performActions
* var actions = new Actions(bigMouse)
* actions.tick.bigMouseDown().tick.bigMouseUp().tick.bigMouseCancel()
*
* @memberof Pointer#
*/
Cancel: () => {
return {
type: 'pointerCancel'
}
},
/**
* Pause the pointer for the specified length of time
*
* This method will be added to the action's `tick` property. **prefixed** with the Pointer's ID.
* @param {number} duration=0 Duration of the pause
*
* @example
* var bigMouse = new Actions.Pointer('bigMouse')
* var bigKeyboard = new Actions.Keyboard('bigKeyboard')
*
* var actions = new Actions(bigMouse, bigKeyboard)
* actions.tick.bigKeyboardDown('a').bigMousePause()
* actions.performActions(actions)
*
* @memberof Pointer#
*/
Pause: (duration) => {
return { type: 'pause', duration }
}
}
}
}
exports = module.exports = Pointer