mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-02-24 14:58:35 +08:00
Fix headline blur on click and improve editor focus
This commit is contained in:
parent
551444ec76
commit
bfe2036d34
2 changed files with 48 additions and 45 deletions
|
@ -231,43 +231,47 @@ function handleElementFocused(hook, focusableId, scroll) {
|
|||
}
|
||||
|
||||
function handleInsertModeChanged(hook, insertMode) {
|
||||
if (hook.state.isFocused) {
|
||||
const input = getInput(hook);
|
||||
|
||||
if (hook.state.isFocused && !hook.state.insertMode && insertMode) {
|
||||
hook.state.insertMode = insertMode;
|
||||
|
||||
if (hook.state.liveEditor) {
|
||||
if (hook.state.insertMode) {
|
||||
// For some reason, when clicking the editor for a brief moment it is
|
||||
// already focused and the cursor is in the previous location, which
|
||||
// makes the browser immediately scroll there. We blur the editor,
|
||||
// then wait for the editor to update the cursor position, finally
|
||||
// we focus the editor and scroll if the cursor is not in the view
|
||||
// (when entering insert mode with "i").
|
||||
hook.state.liveEditor.blur();
|
||||
setTimeout(() => {
|
||||
hook.state.liveEditor.focus();
|
||||
// The insert mode may be enabled as a result of clicking the editor,
|
||||
// in which case we want to wait until editor handles the click
|
||||
// and sets new cursor position.
|
||||
// To achieve this, we simply put this task at the end of event loop,
|
||||
// ensuring all click handlers are executed first.
|
||||
setTimeout(() => {
|
||||
scrollIntoView(document.activeElement, {
|
||||
scrollMode: "if-needed",
|
||||
behavior: "smooth",
|
||||
block: "center",
|
||||
});
|
||||
}, 0);
|
||||
scrollIntoView(document.activeElement, {
|
||||
scrollMode: "if-needed",
|
||||
behavior: "smooth",
|
||||
block: "center",
|
||||
});
|
||||
}, 0);
|
||||
|
||||
broadcastSelection(hook);
|
||||
} else {
|
||||
hook.state.liveEditor.blur();
|
||||
}
|
||||
broadcastSelection(hook);
|
||||
}
|
||||
|
||||
const input = getInput(hook);
|
||||
if (input) {
|
||||
input.focus();
|
||||
// selectionStart is only supported on text based input
|
||||
if (input.selectionStart !== null) {
|
||||
input.selectionStart = input.selectionEnd = input.value.length;
|
||||
}
|
||||
}
|
||||
} else if (hook.state.insertMode && !insertMode) {
|
||||
hook.state.insertMode = insertMode;
|
||||
|
||||
if (hook.state.liveEditor) {
|
||||
hook.state.liveEditor.blur();
|
||||
}
|
||||
|
||||
if (input) {
|
||||
if (hook.state.insertMode) {
|
||||
input.focus();
|
||||
// selectionStart is only supported on text based input
|
||||
if (input.selectionStart !== null) {
|
||||
input.selectionStart = input.selectionEnd = input.value.length;
|
||||
}
|
||||
} else {
|
||||
input.blur();
|
||||
}
|
||||
input.blur();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,25 +95,24 @@ function handleElementFocused(hook, cellId, scroll) {
|
|||
}
|
||||
|
||||
function handleInsertModeChanged(hook, insertMode) {
|
||||
if (hook.state.isFocused) {
|
||||
const heading = getHeading(hook);
|
||||
|
||||
if (hook.state.isFocused && !hook.state.insertMode && insertMode) {
|
||||
hook.state.insertMode = insertMode;
|
||||
|
||||
const heading = getHeading(hook);
|
||||
|
||||
if (hook.state.insertMode) {
|
||||
// While in insert mode, ignore the incoming changes
|
||||
hook.el.setAttribute("phx-update", "ignore");
|
||||
heading.setAttribute("contenteditable", "true");
|
||||
heading.focus();
|
||||
moveSelectionToEnd(heading);
|
||||
} else {
|
||||
heading.removeAttribute("contenteditable");
|
||||
hook.el.removeAttribute("phx-update");
|
||||
hook.pushEvent(hook.props.onValueChange, {
|
||||
value: headingValue(heading),
|
||||
metadata: hook.props.metadata,
|
||||
});
|
||||
}
|
||||
// While in insert mode, ignore the incoming changes
|
||||
hook.el.setAttribute("phx-update", "ignore");
|
||||
heading.setAttribute("contenteditable", "true");
|
||||
heading.focus();
|
||||
moveSelectionToEnd(heading);
|
||||
} else if (hook.state.insertMode && !insertMode) {
|
||||
hook.state.insertMode = insertMode;
|
||||
heading.removeAttribute("contenteditable");
|
||||
hook.el.removeAttribute("phx-update");
|
||||
hook.pushEvent(hook.props.onValueChange, {
|
||||
value: headingValue(heading),
|
||||
metadata: hook.props.metadata,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue