import { type SugarElement, SugarLocation, SugarNode, Traverse } from '@ephox/sugar'; const point = (type: string, element: SugarElement, x: number, y: number): void => { const touch = { identifier: Date.now(), target: element.dom, clientX: x, clientY: y, pageX: x, pageY: y, radiusX: 2.5, radiusY: 2.5, rotationAngle: 10, force: 0.5 }; // Adapted from https://stackoverflow.com/a/42447620/11275515 if (typeof TouchEvent === 'function' && typeof Touch === 'function') { const touchAction = new Touch(touch); const ev: TouchEvent = new TouchEvent(type, { cancelable: true, bubbles: true, view: window, touches: [ touchAction ], targetTouches: [], changedTouches: [ touchAction ] }); element.dom.dispatchEvent(ev); } else { // No native touch event support, so we need to simulate with a UIEvent const ev: any = new UIEvent(type, { cancelable: true, bubbles: true, view: window }); // Patch in the touch properties ev.touches = [ touch ]; ev.targetTouches = []; ev.changedTouches = [ touch ]; element.dom.dispatchEvent(ev); } }; const findElement = (element: SugarElement): SugarElement => (SugarNode.isText(element) ? Traverse.parent(element).getOrDie() : element) as SugarElement; const touch = (eventType: string) => (element: SugarElement): void => { const position = SugarLocation.absolute(findElement(element)); point(eventType, element, position.left, position.top); }; const touchAt = (eventType: string) => (dx: number, dy: number) => (element: SugarElement): void => { const position = SugarLocation.absolute(findElement(element)); point(eventType, element, position.left + dx, position.top + dy); }; const touchstart = touch('touchstart'); const touchstartAt = touchAt('touchstart'); const touchend = touch('touchend'); const touchendAt = touchAt('touchend'); const touchmove = touch('touchmove'); const touchmoveTo = touchAt('touchmove'); export { touchstart, touchstartAt, touchend, touchendAt, touchmove, touchmoveTo, point };