Skip to content

Commit

Permalink
Rewrite hotkeys in plain JS
Browse files Browse the repository at this point in the history
This fixes bugs with latest jQuery version that does not reliably trigger click events
anymore.
  • Loading branch information
tvdeyen committed Mar 14, 2024
1 parent 396f055 commit 787d51f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Alchemy.ElementsWindow =
@callback = callback
@element_window.append @createToolbar(options.toolbarButtons)
@element_window.append @element_area
Alchemy.GUI.init(@element_window)
@button = $('#element_window_button')
@button.on "click", =>
@hide()
Expand Down
81 changes: 40 additions & 41 deletions app/javascript/alchemy_admin/hotkeys.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,60 @@
import "keymaster"

Alchemy = window.Alchemy || {}
Alchemy.bindedHotkeys = []
const bindedHotkeys = []

export default function (scope) {
// Unbind all previously registered hotkeys.
if (!scope) {
$(document).off("keypress")
Alchemy.bindedHotkeys.forEach((hotkey) => key.unbind(hotkey))
function showHelp(evt) {
if (
!$(evt.target).is("input, textarea") &&
String.fromCharCode(evt.which) === "?"
) {
Alchemy.openDialog("/admin/help", {
title: Alchemy.t("help"),
size: "400x492"
})
return false
} else {
return true
}
}

export default function (scope = document) {
// The scope can be a jQuery object because we still use jQuery in Alchemy.Dialog.
if (scope instanceof jQuery) {
scope = scope[0]
}

// Unbind all previously registered hotkeys if we are not inside a dialog.
if (scope === document) {
document.removeEventListener("keypress", showHelp)
document.addEventListener("keypress", showHelp)
bindedHotkeys.forEach((hotkey) => key.unbind(hotkey))
}

// Binds keyboard shortcuts to search fields.
const $search_fields = $(".search_input_field", scope)
const $search_fields_clear = $(
".search_field_clear, .js_filter_field_clear",
scope
const search_fields = scope.querySelectorAll(".search_input_field")
const search_fields_clear = scope.querySelectorAll(
".search_field_clear, .js_filter_field_clear"
)

key("alt+f", function () {
key.setScope("search")
$search_fields.focus()
search_fields.forEach((el) => el.focus({ focusVisible: true }))
return false
})
Alchemy.bindedHotkeys.push("alt+f")

bindedHotkeys.push("alt+f")
key("esc", "search", function () {
$search_fields_clear.click()
$search_fields.blur()
search_fields_clear.forEach((el) => el.click())
search_fields.forEach((el) => el.blur())
})
Alchemy.bindedHotkeys.push("esc")

if (!scope) {
$(document).on("keypress", function (e) {
if (
!$(e.target).is("input, textarea") &&
String.fromCharCode(e.which) === "?"
) {
Alchemy.openDialog("/admin/help", {
title: Alchemy.t("help"),
size: "400x492"
})
return false
} else {
return true
}
})
}
bindedHotkeys.push("esc")

// Binds click events to hotkeys.
// Binds click events to buttons with hotkeys.
//
// Simply add a data-alchemy-hotkey attribute to your link.
// If a hotkey is triggered by user, the click event of the element gets triggerd.
//
$("[data-alchemy-hotkey]", scope).each(function () {
const $this = $(this)
const hotkey = $this.data("alchemy-hotkey")
key(hotkey, () => $this.click())
Alchemy.bindedHotkeys.push(hotkey)
scope.querySelectorAll("[data-alchemy-hotkey]").forEach(function (el) {
const hotkey = el.dataset.alchemyHotkey
key(hotkey, () => el.click())
bindedHotkeys.push(hotkey)
})
}

0 comments on commit 787d51f

Please sign in to comment.