iOS application fails to respond to mouse and touch events - javascript

I am developing an iOS application using Swift that incorporates web content by using WKWebView.
[URL Loading and Goal] Once a URL has been loaded inside this web view, I want to open a keyboard whenever the user wants to type.
[JavaScript Events] As browsing is based on eye coordinates, I want a JavaScript event to be triggered when the user's gaze is focused on an input field. On the basis of eye gaze coordinates, I can determine the underlying element of the webpage document. After this, I want to trigger a mouse event/touch event for clicks within the input element.
However, the system-level keyboard does not appear if I follow these steps.
Code:
touchPoint variable contains the current x and y coordinates of the eye gaze.
#IBOutlet var webView : WKWebView!
let jsStyle = """
function sendTouchEvent(x, y, element, eventType) {
const touchObj = new Touch({
identifier: Date.now(),
target: element,
clientX: x,
clientY: y,
radiusX: 2.5,
radiusY: 2.5,
rotationAngle: 10,
force: 0.5,
});
const touchEvent = new TouchEvent(eventType, {
cancelable: true,
bubbles: true,
touches: [touchObj],
targetTouches: [],
changedTouches: [touchObj],
shiftKey: true,
});
element.dispatchEvent(touchEvent);
}
function click(x, y)
{
var ev = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true,
'screenX': x,
'screenY': y
});
var el = document.elementFromPoint(x, y);
if(el.nodeName == "INPUT") {
el.autofocus = true;
el.click();
el.focus();
sendTouchEvent(x, y, el, 'touchstart');
}
try {
el.dispatchEvent(ev);
} catch(error) {
console.log(error);
}
}
click(\(touchPoint.x), \(touchPoint.y));
"""
webView.evaluateJavaScript(jsStyle, completionHandler : { result, error in
print("### Evaluate JavaScript for current click!")
} => Called when eye gaze coordinates are received.
[Temporary Solution] In order to make this work, I created a native UITextField that acts as a proxy for the webpage element and opens the keyboard by becoming the first responder when I determine using JS that the eye gaze is focused on an input element.
My goal, however, is to remove the proxy logic and replace it with JavaScript code that opens the system-level keyboard.

Related

How to use mousevent 'click' on a 'video' element?

I'm trying to click on a Facebook web game using this js function:
onmousemove = function(e){console.log("mouse location:", e.clientX, e.clientY)}
function click(x, y)
{
var ev = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true,
'screenX': x,
'screenY': y
});
var el = document.elementFromPoint(x, y);
el.dispatchEvent(ev);
}
click(796,77)
The click works everywhere in the Facebook page, less inside the game area.
When i hover it with dev tools > inspect element, the game area show: video._1yvx
game area:
https://i.imgur.com/vctnIIA.png
dev tools: https://i.imgur.com/YqmVLYt.png
Looking for help on this

Prevent actual mouse movement from interfering with simulated mousemove event in javascript

I'm currently working on an automated tool that reproduce hand-drawing previously recorded on a canvas. I'm using fabric.js to create a canvas and free draw on it.
In this part of the application, the user can't draw anything but is watching the canvas being drawn on. That's why the canvas is behind an invisible div that blocks all interactions.
So far, I managed to recreate the drawing process using an asynchronous function and by triggering well-timed mouse events at specific locations.
Let's start with some mouse coordinates to use for the path to draw :
var coord = [
{x: 927, y: 115},
{x: 925, y: 116},
{x: 922, y: 116},
{x: 910, y: 115},
{x: 899, y: 114}
]
I use a custom function that simulates a mouse event at a specific location :
function simulateMouseEvent(e, eventName, x, y) {
e.dispatchEvent(new MouseEvent(eventName, {
view: window,
bubbles: true,
cancelable: true,
clientX: x,
clientY: y,
button: 0
}));
}
To start, I trigger a mousedown event as if the user was clicking on the canvas :
simulateMouseEvent(canvasElement, 'mousedown', coord[0].x, coord[0].y);
Then a for loop launches a bunch of consecutive mousemove events every 200 ms like so :
for (i = 1; i < coord.length; i++) {
await movement(coord[i]);
}
function movement(coordinates) {
return new Promise(function(resolve, reject) {
simulateMouseEvent(canvasElement, 'mousemove', coordinates.x, coordinates.y);
setTimeout(function() {
resolve('');
}, 200);
})
}
Finally, I stop the drawing by triggering a mouseup event like so :
var last = coord[coord.length - 1];
simulateMouseEvent(canvasElement, 'mouseup' last.x, last.y);
So everything works fine if the user's cursor is not above the canvas (which is what happens most of the time) even though there is a mask theoretically blocking the user's interaction with the canvas.
I believe that triggering a mouse event on a div "activates" it even if that div can't be reached. I tried adding pointer-events: none on the css rule of the canvas wih no difference. Is there a way to block real mouse cursor events while triggering fake ones ?

Chrome extension click bot in webGL

I am trying to develop a chrome plugin that will record a series of click and play them back
I have seen that you can simulate a click on a DOM element but the problem is in my case, I only have a webGL canvas and the buttons are not directly accessible
I have managed to get the user's click position using this :
document.onclick = function(e)
{
var x = e.pageX;
var y = e.pageY;
console.log(x + " " + y)
//browser.runtime.sendMessage({"message": "open_new_tab", "url": "aze"});
};
But I haven't found anything to use these positions to perform a click action on the page
If I understand your question properly, you want to simulate a click on the webpage?
JavaScript has the click() method exposed for all elements:
element.click()
If you don't know the element, but just the positions:
document.elementFromPoint(x, y).click()
You can dispatch a mouse click at a specific position:
const = (x, y) => {
const ev = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true,
'screenX': x,
'screenY': y
})
const el = document.elementFromPoint(x, y);
el.dispatchEvent(ev);
}
All the above should be done via Content Script within the extension.

.setCapture and .releaseCapture in Chrome

I have an HTML5 canvas based Javascript component that needs to capture and release mouse events. In the control the user clicks an area inside it and drags to affect a change. On PC I would like the user to be able to continue dragging outside of the browser and for the canvas to receive the mouse up event if the button is released outside of the window.
However, according to my reading setCapture and releaseCapture aren't supported on Chrome.
Is there a workaround?
An article written in 2009 details how you can implement cross-browser dragging which will continue to fire mousemove events even if the user's cursor leaves the window.
http://news.qooxdoo.org/mouse-capturing
Here's the essential code from the article:
function draggable(element) {
var dragging = null;
addListener(element, "mousedown", function(e) {
var e = window.event || e;
dragging = {
mouseX: e.clientX,
mouseY: e.clientY,
startX: parseInt(element.style.left),
startY: parseInt(element.style.top)
};
if (element.setCapture) element.setCapture();
});
addListener(element, "losecapture", function() {
dragging = null;
});
addListener(document, "mouseup", function() {
dragging = null;
}, true);
var dragTarget = element.setCapture ? element : document;
addListener(dragTarget, "mousemove", function(e) {
if (!dragging) return;
var e = window.event || e;
var top = dragging.startY + (e.clientY - dragging.mouseY);
var left = dragging.startX + (e.clientX - dragging.mouseX);
element.style.top = (Math.max(0, top)) + "px";
element.style.left = (Math.max(0, left)) + "px";
}, true);
};
draggable(document.getElementById("drag"));
The article contains a pretty good explanation of what's going on, but there are a few gaps where knowledge is assumed. Basically (I think), in Chrome and Safari, if you handle mousemove on the document then, if the user clicks down and holds the mouse, the document will continue receiving mousemove events even if the cursor leaves the window. These events will not propagate to child nodes of the document, so you have to handle it at the document level.
Chrome supports setPointerCapture, which is part of the W3C Pointer events recommendation. Thus an alternative would be to use pointer events and these methods.
You might want to use the jquery Pointer Events Polyfill to support other browsers.

javascript: How can find the location in screen/webpage to click

I need to build and automate task where I need to click a button in a web page but I don't know how can I get the location on screen. Any of you can be so kind and help me to figure out how to get position on screen to click ?
I'll really appreciate your help.
Here is a javascript function I wrote to simulate clicking a link. I think you can adapt it pretty easily to click any object in a page that has a valid ID:
function ClickLink(AnchorName)
{
var evt = document.createEvent("MouseEvents");
var Link = document.getElementById(AnchorName);
var LinkForJquery = '#' + AnchorName
var x = $(LinkForJquery).offset().left;
var y = $(LinkForJquery).offset().top;
evt.initMouseEvent("click", true, true, window, 1, 0, 0, x, y, false, false, false, false, 0, null);
var allowDefault = Link.dispatchEvent(evt);
}

Categories

Resources