mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-10-09 13:07:37 +08:00
Disable keyboard control when an editable element is focused (#885)
This commit is contained in:
parent
f7fcb8f884
commit
3a0d77d879
2 changed files with 33 additions and 4 deletions
|
@ -1,5 +1,5 @@
|
||||||
import { getAttributeOrThrow, parseBoolean } from "../lib/attribute";
|
import { getAttributeOrThrow, parseBoolean } from "../lib/attribute";
|
||||||
import { cancelEvent } from "../lib/utils";
|
import { cancelEvent, isEditableElement } from "../lib/utils";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A hook for ControlComponent to handle user keyboard interactions.
|
* A hook for ControlComponent to handle user keyboard interactions.
|
||||||
|
@ -30,6 +30,13 @@ const KeyboardControl = {
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener("keyup", this.handleDocumentKeyUp, true);
|
window.addEventListener("keyup", this.handleDocumentKeyUp, true);
|
||||||
|
|
||||||
|
this.handleDocumentFocus = (event) => {
|
||||||
|
handleDocumentFocus(this, event);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Note: the focus event doesn't bubble, so we register for the capture phase
|
||||||
|
window.addEventListener("focus", this.handleDocumentFocus, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
updated() {
|
updated() {
|
||||||
|
@ -39,6 +46,7 @@ const KeyboardControl = {
|
||||||
destroyed() {
|
destroyed() {
|
||||||
window.removeEventListener("keydown", this.handleDocumentKeyDown, true);
|
window.removeEventListener("keydown", this.handleDocumentKeyDown, true);
|
||||||
window.removeEventListener("keyup", this.handleDocumentKeyUp, true);
|
window.removeEventListener("keyup", this.handleDocumentKeyUp, true);
|
||||||
|
window.removeEventListener("focus", this.handleDocumentFocus, true);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,6 +92,12 @@ function handleDocumentKeyUp(hook, event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleDocumentFocus(hook, event) {
|
||||||
|
if (hook.props.isKeydownEnabled && isEditableElement(event.target)) {
|
||||||
|
hook.pushEventTo(hook.props.target, "disable_keyboard", {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function keyboardEnabled(hook) {
|
function keyboardEnabled(hook) {
|
||||||
return hook.props.isKeydownEnabled || hook.props.isKeyupEnabled;
|
return hook.props.isKeydownEnabled || hook.props.isKeyupEnabled;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,9 +61,18 @@ defmodule LivebookWeb.Output.ControlComponent do
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event("toggle_keyboard", %{}, socket) do
|
def handle_event("toggle_keyboard", %{}, socket) do
|
||||||
socket = update(socket, :keyboard_enabled, ¬/1)
|
socket = update(socket, :keyboard_enabled, ¬/1)
|
||||||
|
maybe_report_status(socket)
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
if :status in socket.assigns.attrs.events do
|
def handle_event("disable_keyboard", %{}, socket) do
|
||||||
report_event(socket, %{type: :status, enabled: socket.assigns.keyboard_enabled})
|
socket =
|
||||||
|
if socket.assigns.keyboard_enabled do
|
||||||
|
socket = assign(socket, keyboard_enabled: false)
|
||||||
|
maybe_report_status(socket)
|
||||||
|
socket
|
||||||
|
else
|
||||||
|
socket
|
||||||
end
|
end
|
||||||
|
|
||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
|
@ -84,6 +93,12 @@ defmodule LivebookWeb.Output.ControlComponent do
|
||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp maybe_report_status(socket) do
|
||||||
|
if :status in socket.assigns.attrs.events do
|
||||||
|
report_event(socket, %{type: :status, enabled: socket.assigns.keyboard_enabled})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp report_event(socket, attrs) do
|
defp report_event(socket, attrs) do
|
||||||
topic = socket.assigns.attrs.ref
|
topic = socket.assigns.attrs.ref
|
||||||
event = Map.merge(%{origin: self()}, attrs)
|
event = Map.merge(%{origin: self()}, attrs)
|
||||||
|
|
Loading…
Add table
Reference in a new issue