Did you drop your phone again while typing? You cannot undo dropping your phone, but at least you can undo the typing you’ve done on your phone before breaking the back glass.
But what actually happens in the DOM when you undo typing?
Let’s create a textarea and capture all events to see what events are actually triggered on undo. Creating a textarea is easy enough, but how do we capture all events? There isn’t a addEventListener("*")
for any event.
After some googling, some suggest iterating over all properties that start with on
: onkeydown
, onkeyup
, etc. Let’s try that!
const textarea = document.createElement("textarea");
document.body.appendChild(textarea);
const pre = document.createElement("pre");
document.body.appendChild(pre);
const eventNames = [];
for (const key in textarea) {
if (key.substr(0, 2) === "on") {
eventNames.push(key.substr(2));
}
}
console.log(eventNames); /* ["copy", "cut", "paste", "abort", "blur", "cancel", "canplay",
"canplaythrough", "change", "click", "close", "contextmenu", "cuechange",
"dblclick", "drag", "dragend", "dragenter", "dragleave", "dragover", "dragstart",
"drop", "durationchange", "emptied", "ended", "error", "focus", "input", "invalid",
"keydown", "keypress", "keyup", "load", "loadeddata", "loadedmetadata", "loadstart",
"mousedown", "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup",
"mousewheel", "pause", "play", "playing", "progress", "ratechange", "reset", "resize",
"scroll", "seeked", "seeking", "select", "stalled", "submit", "suspend", "timeupdate",
"toggle", "volumechange", "waiting", "wheel", "auxclick", "gotpointercapture",
"lostpointercapture", "pointerdown", "pointermove", "pointerup", "pointercancel",
"pointerover", "pointerout", "pointerenter", "pointerleave", "selectstart", "selectionchange",
"animationend", "animationiteration", "animationstart", "transitionend", "formdata",
"pointerrawupdate", "beforecopy", "beforecut", "beforepaste", "search", "fullscreenchange",
"fullscreenerror", "webkitfullscreenchange", "webkitfullscreenerror"] */
const eventCounts = {};
for (const eventName of eventNames) {
textarea.addEventListener(eventName, (event) => {
if (!eventCounts[eventName]) {
eventCounts[eventName] = 0;
}
console.log(eventName, event);
eventCounts[eventName]++;
pre.textContent = JSON.stringify(eventCounts, null, 2);
});
}
That’s a LOT of events. I never actually realised there were so many!
Testing this in my desktop browser, there seems to be an input
event I didn’t know about. The input event is triggered (together with keyboard events) when using Ctrl + Z. Even when using the Cut feature from the Edit toolbar of the browser (I mean, who does that?), an input
event is triggered, together with a cut
event.
Now let’s try the undo feature on my phone: I enter some text, shake the phone, and press undo. Only an input
event is triggered!
So what’s this InputEvent? Let’s see what Mozzila has to say:
Looks like there is all kinds of interesting data on the InputEvent interface.
Most notably: event.inputType
is "historyUndo"
. Is this even a documented standard somewhere? Looking at InputEvent’s inputType specification at w3c, there is an editor’s draft containing a list of inputType values:
Both "historyUndo"
and "historyRedo"
are there. Cool.
So there’s that: When you undo typing on your browser, a special input
event is triggered, with inputType = "historyUndo"
. Now you know.