sanjar-notes / frontend

The basics - HTML, CSS, Javascript, browser APIs, performance
3 stars 0 forks source link

`isTrusted` - differentiate human vs script triggered event #104

Open sanjarcode opened 1 year ago

sanjarcode commented 1 year ago

Concept, usage

All events of the browser (as available in the handler callbacks like onchange etc) have a isTrusted property. This property intends to distinguish if the event was triggered by a user (aka human) vs a script.

There is a gotcha here - usual programmatically triggered events (example videoNode.pause()) will still generate a pause event with isTrusted true). Weird ik.

To programmatically fire an event (such that isTrusted in the event would be false), one needs to do it via dispatchEvent. Code:

function toggleVideoIntentionalBot(videoNode) {
  const event = new Event('pause', { bubbles: true });
  videoNode.dispatchEvent(event);

  // event isTrusted would be false
}

function toggleVideoUsual(videoNode) {
  videoNode.pause();

  // event isTrusted would be true
}

To sum it up, there are 3 cases:

  1. Human/user triggers event - event.isTrusted is true
  2. Usual programmatic trigger - event.isTrusted is true
  3. Event via dispatchEvent - event.isTsuted is false

Context

I have a custom browser script (search toggleStudyPauseMode) that pauses the video if I move to another tab, or move out of the window. And resumes the video when I focus back on the original tab.

It's very helpful for software courses since I go to the editor/terminal to try something, but the video keeps playing, which is annoying. This auto-pause is great.

But there was a small problem, my script naively toggled the state whenever I changed focus. i.e. even if I had intentionally paused the video, then changed to a different tab and came back, the video would start playing.

The solution is to add a variable to this script that keeps track of whether the video was deliberately (human) paused, or the script itself did it. The script could then respect the state and do nothing if the video was manually paused.