18

I'm trying to automatize some tasks in JavaScript and I need to use a InputEvent, but when I use normal event, I'm getting event.isTrusted = false and my event is doing nothing. Here is my event code:

var event = new InputEvent('input', {
    bubbles: true,
    cancelable: false,
    data: "a"
}); 

document.getElementById('email').dispatchEvent(event);

This code should put "a" into a textField with id "email", but when event.isTrusted = false, this code is doing nothing. I'm testing it in Chrome Developer Tools in Sources tab with Event Listener Breakpoints (I checked only keyboard>input breakpoint and it shows me all attributes of used event). I checked all attributes from real keyboard click and only thing that is different is event.isTrusted.

What can I change or what can I do to get event.isTrusted = true?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Higu
  • 193
  • 1
  • 1
  • 10

5 Answers5

10

The isTrusted read-only property of the Event interface is a boolean that is true when the event was generated by a user action, and false when the event was created or modified by a script or dispatched via dispatchEvent.

Source: MDN

You may have misunderstood the concept of the Input Event, the event is triggered after the user type in the input. Manually triggering the event will not make the inputs change their values, is the changing of the values that makes the input trigger's the event not the opposite.

If you really want to change the value of the inputs with a custom event you can do something like this:

let TargetInput = document.getElementById('target')
let Button = document.getElementById('btnTrigger');

Button.addEventListener('click',function(e){
    Trigger();
}, false);

TargetInput.addEventListener('input',function(e){
    if(!e.isTrusted){
  //Mannually triggered
  this.value += e.data;
 }
}, false);

function Trigger(){
 var event = new InputEvent('input', {
  bubbles: true,
  cancelable: false,
  data: "a"
 }); 

 TargetInput.dispatchEvent(event);
}
Target: <input type="text" id="target">

<hr>

<button id="btnTrigger">Trigger Event</button>
Matheus Cuba
  • 2,068
  • 1
  • 20
  • 31
10

Any addEventListener call after the following code is executed will have isTrusted set to true.

Element.prototype._addEventListener = Element.prototype.addEventListener;
Element.prototype.addEventListener = function () {
    let args = [...arguments]
    let temp = args[1];
    args[1] = function () {
        let args2 = [...arguments];
        args2[0] = Object.assign({}, args2[0])
        args2[0].isTrusted = true;
        return temp(...args2);
    }
    return this._addEventListener(...args);
}

Note: This is a very "hacky" way to go about doing this.

Jaime Argila
  • 408
  • 3
  • 13
  • 1
    good workaround if there is no security risk going this route. Now code that fire default action runs at higher privileges. – khaled Jun 23 '21 at 18:04
  • Does this still work? In TypeScript at least it does not. – Paul Nov 11 '22 at 15:14
  • If this works, it probably is a security bug and will eventually get fixed. That flag has been added for a reason. – Oktokolo Nov 30 '22 at 05:46
  • 2
    I'm confused as isTrusted is a readonly property and as far as my understanding goes, it can't be altered in code, therefore my intuition is that this code doesn't work. Otherwise it defeats the purpose of isTrusted as one can't really trust its value. What am I missing here? Here is the reference to the doc for isTrusted: https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted. Also "In Chrome, Firefox and Opera, the event is trusted if it is invoked by the user, and not trusted if it is invoked by a script." as found on https://www.w3schools.com/jsref/event_istrusted.asp – vir us Feb 06 '23 at 20:48
4

Unfortunately, you cannot generate event programmatically with isTrusted=true in Google Chrome and others modern browser. See https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted

mlosev
  • 5,130
  • 1
  • 19
  • 31
  • This makes me wonder how on-screen keyboards work. For example when inputting Arabic characters, or even in the daily wordle game – mosaic Jul 27 '23 at 10:52
3

Pupeeteer might help. It generates trusted events.

In browsers, input events could be divided into two big groups: trusted vs. untrusted.

Trusted events: events generated by users interacting with the page, e.g. using a mouse or keyboard. Untrusted event: events generated by Web APIs, e.g. document.createEvent or element.click() methods. Websites can distinguish between these two groups:

  • using an Event.isTrusted event flag
  • sniffing for accompanying events. For example, every trusted 'click' event is preceded by 'mousedown' and 'mouseup' events.

For automation purposes it’s important to generate trusted events. All input events generated with Puppeteer are trusted and fire proper accompanying events.

Eugene Karataev
  • 1,777
  • 1
  • 11
  • 24
0

I've found it's not possible to set isTrusted to true BUT, depending on your need, a potential solution would be to create a local override in DevTools and remove the conditional in code for the script. This will tell Chrome to use your version (with the isTrusted check removed) instead of the site's JS file.

docta_faustus
  • 2,383
  • 4
  • 30
  • 47