Skip to content

Instantly share code, notes, and snippets.

@kch
Last active June 11, 2023 03:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kch/29a328a797be4f43a3d29bcbbd9df6c3 to your computer and use it in GitHub Desktop.
Save kch/29a328a797be4f43a3d29bcbbd9df6c3 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name ⌘⌫ Element
// @description ⌘⌫ deletes element under cursor, ⌘Z puts back
// @match *://*.*
// ==/UserScript==
let undoWindow = 3000 // can undo for this long
let undoCooldown = 1500 // will prevent default undo for this long after last undo
let scheduledDeletion = null // timeout id for deleteElements
let lastHide = 0 // timestamp for last element was hidden
let lastUndo = 0 // timestamp for last successful undo
let hiddenElements = [] // elements that can be unhidden by undo
let cmdCombo = (ev, key) => !ev.shiftKey && !ev.ctrlKey && !ev.altKey && ev.metaKey && ev.key == key
let tsWithin = (ts, t) => (Date.now() - ts) <= t
let deleteElements = () => { let e; while ([e,] = hiddenElements.pop()||[]) e.parentNode.removeChild(e) }
document.addEventListener('keydown', function(ev) {
if (cmdCombo(ev, 'Backspace')) {
let el = [...document.querySelectorAll(":hover")].pop() // get innermost elem with under pointer
hiddenElements.push([el, el.style.display]) // keep track of it for undo
el.style.display = 'none' // hide it
lastHide = Date.now() // timestamp for undo window window
clearTimeout(scheduledDeletion) // clear pending deletion to extend undo window
scheduledDeletion = setTimeout(deleteElements, undoWindow + 1) // really delete elements after undo window times out
ev.preventDefault()
}
if (cmdCombo(ev, 'z') && tsWithin(lastHide, undoWindow)) {
let [el, d] = hiddenElements.pop() || []
if (el) {
el.style.display = d
lastUndo = Date.now()
}
// preventDefault if we restored an element, or if it's only been 1500ms since last undo,
// so you don't accidentally reopen a tab by way of over-undoing
if (el || tsWithin(lastUndo, undoCooldown)) ev.preventDefault()
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment