UNPKG

@testing-library/user-event

Version:
196 lines (191 loc) 8.19 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var index$1 = require('../../event/index.js'); require('../../utils/click/isClickableInput.js'); require('../../utils/dataTransfer/Clipboard.js'); require('../../utils/edit/maxLength.js'); require('../../utils/edit/isEditable.js'); var focus = require('../../utils/focus/focus.js'); require('@testing-library/dom/dist/helpers.js'); var isDisabled = require('../../utils/misc/isDisabled.js'); require('@testing-library/dom'); var selection = require('../../utils/focus/selection.js'); require('../../utils/keyDef/readNextDescriptor.js'); var getTreeDiff = require('../../utils/misc/getTreeDiff.js'); require('../../utils/misc/level.js'); require('../../options.js'); var index = require('./index.js'); var buttons = require('./buttons.js'); /** * This object is the single "virtual" mouse that might be controlled by multiple different pointer devices. */ class Mouse { move(config, position) { const prevPosition = this.position; const prevTarget = this.getTarget(config); this.position = position; if (!index.isDifferentPointerPosition(prevPosition, position)) { return; } const nextTarget = this.getTarget(config); const init = this.getEventInit('mousemove'); const [leave, enter] = getTreeDiff.getTreeDiff(prevTarget, nextTarget); return { leave: ()=>{ if (prevTarget !== nextTarget) { index$1.dispatchUIEvent(config, prevTarget, 'mouseout', init); leave.forEach((el)=>index$1.dispatchUIEvent(config, el, 'mouseleave', init)); } }, enter: ()=>{ if (prevTarget !== nextTarget) { index$1.dispatchUIEvent(config, nextTarget, 'mouseover', init); enter.forEach((el)=>index$1.dispatchUIEvent(config, el, 'mouseenter', init)); } }, move: ()=>{ index$1.dispatchUIEvent(config, nextTarget, 'mousemove', init); this.modifySelecting(config); } }; } down(config, keyDef, pointer) { const button = this.buttons.down(keyDef); if (button === undefined) { return; } const target = this.getTarget(config); this.buttonDownTarget[button] = target; const disabled = isDisabled.isDisabled(target); const init = this.getEventInit('mousedown', keyDef.button); if (disabled || index$1.dispatchUIEvent(config, target, 'mousedown', init)) { this.startSelecting(config, init.detail); focus.focus(target); } if (!disabled && buttons.getMouseEventButton(keyDef.button) === 2) { index$1.dispatchUIEvent(config, target, 'contextmenu', this.getEventInit('contextmenu', keyDef.button, pointer)); } } up(config, keyDef, pointer) { const button = this.buttons.up(keyDef); if (button === undefined) { return; } const target = this.getTarget(config); if (!isDisabled.isDisabled(target)) { index$1.dispatchUIEvent(config, target, 'mouseup', this.getEventInit('mouseup', keyDef.button)); this.endSelecting(); const clickTarget = getTreeDiff.getTreeDiff(this.buttonDownTarget[button], target)[2][0]; if (clickTarget) { const init = this.getEventInit('click', keyDef.button, pointer); if (init.detail) { index$1.dispatchUIEvent(config, clickTarget, init.button === 0 ? 'click' : 'auxclick', init); if (init.button === 0 && init.detail === 2) { index$1.dispatchUIEvent(config, clickTarget, 'dblclick', { ...this.getEventInit('dblclick', keyDef.button), detail: init.detail }); } } } } } resetClickCount() { this.clickCount.reset(); } getEventInit(type, button, pointer) { const init = { ...this.position.coords }; if (pointer) { init.pointerId = pointer.pointerId; init.pointerType = pointer.pointerType; init.isPrimary = pointer.isPrimary; } init.button = buttons.getMouseEventButton(button); init.buttons = this.buttons.getButtons(); if (type === 'mousedown') { init.detail = this.clickCount.getOnDown(init.button); } else if (type === 'mouseup') { init.detail = this.clickCount.getOnUp(init.button); } else if (type === 'click' || type === 'auxclick') { init.detail = this.clickCount.incOnClick(init.button); } return init; } getTarget(config) { var _target; return (_target = this.position.target) !== null && _target !== void 0 ? _target : config.document.body; } startSelecting(config, clickCount) { var ref, ref1; // TODO: support extending range (shift) this.selecting = selection.setSelectionPerMouseDown({ document: config.document, target: this.getTarget(config), node: (ref = this.position.caret) === null || ref === void 0 ? void 0 : ref.node, offset: (ref1 = this.position.caret) === null || ref1 === void 0 ? void 0 : ref1.offset, clickCount }); } modifySelecting(config) { var ref, ref1; if (!this.selecting) { return; } selection.modifySelectionPerMouseMove(this.selecting, { document: config.document, target: this.getTarget(config), node: (ref = this.position.caret) === null || ref === void 0 ? void 0 : ref.node, offset: (ref1 = this.position.caret) === null || ref1 === void 0 ? void 0 : ref1.offset }); } endSelecting() { this.selecting = undefined; } constructor(){ this.position = {}; this.buttons = new buttons.Buttons(); this.buttonDownTarget = {}; // According to spec the `detail` on click events should be the number // of *consecutive* clicks with a specific button. // On `mousedown` and `mouseup` it should be this number increased by one. // But the browsers don't implement it this way. // If another button is pressed, // in Webkit: the `mouseup` on the previously pressed button has `detail: 0` and no `click`/`auxclick`. // in Gecko: the `mouseup` and click events have the same detail as the `mousedown`. // If there is a delay while a button is pressed, // the `mouseup` and `click` are normal, but a following `mousedown` starts a new click count. // We'll follow the minimal implementation of Webkit. this.clickCount = new class { incOnClick(button) { const current = this.down[button] === undefined ? undefined : Number(this.down[button]) + 1; this.count = this.count[button] === undefined ? {} : { [button]: Number(this.count[button]) + 1 }; return current; } getOnDown(button) { var _button; this.down = { [button]: (_button = this.count[button]) !== null && _button !== void 0 ? _button : 0 }; var _button1; this.count = { [button]: (_button1 = this.count[button]) !== null && _button1 !== void 0 ? _button1 : 0 }; return Number(this.count[button]) + 1; } getOnUp(button) { return this.down[button] === undefined ? undefined : Number(this.down[button]) + 1; } reset() { this.count = {}; } constructor(){ this.down = {}; this.count = {}; } }(); } } exports.Mouse = Mouse;