mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-12-26 01:53:13 +08:00
Fix inserting accents into the text editor via long-press on MacOS
Related: https://github.com/ianstormtaylor/slate/pull/3041, https://github.com/ianstormtaylor/slate/issues/982
This commit is contained in:
parent
1ebaa3d46c
commit
6ab1b642b7
1 changed files with 69 additions and 0 deletions
|
@ -44,3 +44,72 @@ document.addEventListener(
|
|||
},
|
||||
true
|
||||
);
|
||||
|
||||
/*
|
||||
On MacOS, you can press and hold some keys to see available accent characters, and then
|
||||
press a number or click the option to add the accent. The sequence of events is:
|
||||
|
||||
keydown (key=e)
|
||||
keypress (key=e)
|
||||
keydown (key=e, repeat=true)
|
||||
keydown (key=e, repeat=true)
|
||||
keyup (key=e)
|
||||
... panel is now open ...
|
||||
keydown (key=2) // optional
|
||||
beforeinput (data=é)
|
||||
input (data=é)
|
||||
keyup (key=2)
|
||||
|
||||
In Slate, the result is "eé" instead of the accented mark replacing the initial e.
|
||||
|
||||
This is a patch similar to https://github.com/ianstormtaylor/slate/pull/3041 and is
|
||||
unfortunately a bit of a state machine. If we see the exact series of steps below,
|
||||
we delete the preceding character before inserting the new character:
|
||||
|
||||
1) a keydown with repeat=true
|
||||
2) a keyup for the same key
|
||||
-- no keypress events or non-numeric keydown events --
|
||||
3) a beforeinput event
|
||||
|
||||
Testing notes:
|
||||
- Verify it works when you click an accent option vs choose it with 1,2,3..
|
||||
- Verify that it works when your insertion point is at the beginning, middle and end of string
|
||||
- Verify that it works if the text contains underlined misspellings (fragments)
|
||||
*/
|
||||
|
||||
let repeatingKeyDown = null;
|
||||
let substitutionsPanelMayBeOpen = false;
|
||||
|
||||
document.addEventListener('keydown', e => {
|
||||
repeatingKeyDown = e.repeat ? e.key : null;
|
||||
if (!['1', '2', '3', '4', '5', '6', '7', '8', '9'].includes(e.key)) {
|
||||
substitutionsPanelMayBeOpen = false;
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keypress', e => {
|
||||
substitutionsPanelMayBeOpen = false;
|
||||
});
|
||||
|
||||
document.addEventListener('keyup', e => {
|
||||
substitutionsPanelMayBeOpen = repeatingKeyDown && repeatingKeyDown === e.key;
|
||||
repeatingKeyDown = false;
|
||||
});
|
||||
|
||||
document.addEventListener('beforeinput', e => {
|
||||
if (substitutionsPanelMayBeOpen) {
|
||||
substitutionsPanelMayBeOpen = false;
|
||||
if (e.target instanceof HTMLElement && e.target.closest('[data-slate-editor]')) {
|
||||
console.warn('Manually emitting backspace event for Chrome');
|
||||
|
||||
// You would think that firing keydown AND keyup would be best, but doing that
|
||||
// causes the editor to delete forward if your cursor is not at the end of the text
|
||||
const t = document.createEvent('TextEvent');
|
||||
t.initEvent('keyup', true, true);
|
||||
Object.defineProperty(t, 'keyCode', { value: 8 });
|
||||
Object.defineProperty(t, 'key', { value: 'Backspace' });
|
||||
Object.defineProperty(t, 'code', { value: 'Backspace' });
|
||||
e.target.dispatchEvent(t);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue