add buttons to hotkey input, reset on Del/BackSpace

This commit is contained in:
tophf 2021-08-06 13:04:00 +03:00
parent ba7b55c23d
commit 6798114196
4 changed files with 70 additions and 46 deletions

View File

@ -85,7 +85,10 @@ function createBeautifyUI(scope, options) {
]), ]),
$create('p.beautify-hint', [ $create('p.beautify-hint', [
$create('span', t('styleBeautifyHint') + '\u00A0'), $create('span', t('styleBeautifyHint') + '\u00A0'),
createHotkeyInput('editor.beautify.hotkey', () => moveFocus($('#help-popup'), 0)), createHotkeyInput('editor.beautify.hotkey', {
buttons: false,
onDone: () => moveFocus($('#help-popup'), 0),
}),
]), ]),
$create('.buttons', [ $create('.buttons', [
$create('button', { $create('button', {

View File

@ -795,6 +795,7 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
#help-popup .buttons { #help-popup .buttons {
text-align: center; text-align: center;
margin-top: .75em;
} }
.non-windows #help-popup .buttons { .non-windows #help-popup .buttons {
direction: rtl; direction: rtl;
@ -820,8 +821,8 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
#help-popup .rules p { #help-popup .rules p {
margin: .25em 0; margin: .25em 0;
} }
#help-popup .buttons button { #help-popup .buttons button:nth-child(n + 2) {
margin-right: 3px; margin-left: .5em;
} }
/************ lint ************/ /************ lint ************/

View File

@ -361,13 +361,13 @@ editor.livePreview = (() => {
$('#colorpicker-settings').onclick = function (event) { $('#colorpicker-settings').onclick = function (event) {
event.preventDefault(); event.preventDefault();
const input = createHotkeyInput('editor.colorpicker.hotkey', () => helpPopup.close()); const input = createHotkeyInput('editor.colorpicker.hotkey', {onDone: () => helpPopup.close()});
const popup = helpPopup.show(t('helpKeyMapHotkey'), input); const popup = helpPopup.show(t('helpKeyMapHotkey'), input);
const bounds = this.getBoundingClientRect(); const bounds = this.getBoundingClientRect();
popup.style.left = bounds.right + 10 + 'px'; popup.style.left = bounds.right + 10 + 'px';
popup.style.top = bounds.top - popup.clientHeight / 2 + 'px'; popup.style.top = bounds.top - popup.clientHeight / 2 + 'px';
popup.style.right = 'auto'; popup.style.right = 'auto';
input.focus(); $('input', popup).focus();
}; };
function invokeColorpicker(cm) { function invokeColorpicker(cm) {

View File

@ -103,49 +103,69 @@ function clipString(str, limit = 100) {
} }
/* exported createHotkeyInput */ /* exported createHotkeyInput */
function createHotkeyInput(prefId, onDone = () => {}) { function createHotkeyInput(prefId, {buttons = true, onDone}) {
return $create('input', { const RX_ERR = new RegExp('^(' + [
type: 'search', /Space/,
/(Shift-)?./, // a single character
/(?=.)(Shift-?|Ctrl-?|Control-?|Alt-?|Meta-?)*(Escape|Tab|Page(Up|Down)|Arrow(Up|Down|Left|Right)|Home|End)?/,
].map(r => r.source || r).join('|') + ')$', 'i');
const initialValue = prefs.get(prefId);
const input = $create('input', {
spellcheck: false, spellcheck: false,
value: prefs.get(prefId), onpaste: e => onkeydown(e, e.clipboardData.getData('text')),
onkeydown(event) { onkeydown,
const key = CodeMirror.keyName(event);
if (key === 'Tab' || key === 'Shift-Tab') {
return;
}
event.preventDefault();
event.stopPropagation();
switch (key) {
case 'Enter':
if (this.checkValidity()) onDone(true);
return;
case 'Esc':
onDone(false);
return;
default:
// disallow: [Shift?] characters, modifiers-only, [modifiers?] + Esc, Tab, nav keys
if (!key || new RegExp('^(' + [
'(Back)?Space',
'(Shift-)?.', // a single character
'(Shift-?|Ctrl-?|Alt-?|Cmd-?){0,2}(|Esc|Tab|(Page)?(Up|Down)|Left|Right|Home|End|Insert|Delete)',
].join('|') + ')$', 'i').test(key)) {
this.value = key || this.value;
this.setCustomValidity('Not allowed');
return;
}
}
this.value = key;
this.setCustomValidity('');
prefs.set(prefId, key);
},
oninput() {
// fired on pressing "x" to clear the field
prefs.set(prefId, '');
},
onpaste(event) {
event.preventDefault();
},
}); });
buttons = buttons && [
['confirmOK', 'Enter'],
['undo', initialValue],
['genericResetLabel', ''],
].map(([label, val]) =>
$create('button', {onclick: e => onkeydown(e, val)}, t(label)));
const [btnOk, btnUndo, btnReset] = buttons || [];
onkeydown(null, initialValue);
return buttons
? $create('fragment', [input, $create('.buttons', buttons)])
: input;
function onkeydown(e, key) {
let newValue;
if (e && e.type === 'keydown') {
key = getEventKeyName(e);
}
switch (e && key) {
case 'Tab':
case 'Shift-Tab':
return;
case 'BackSpace':
case 'Delete':
newValue = '';
break;
case 'Enter':
if (input.checkValidity() && onDone) onDone();
break;
case 'Escape':
if (onDone) onDone();
break;
default:
newValue = key.replace(/\b.$/, c => c.toUpperCase());
}
if (newValue != null) {
const error = RX_ERR.test(newValue) ? t('genericError') : '';
if (e && !error) prefs.set(prefId, newValue);
input.setCustomValidity(error);
input.value = newValue;
input.focus();
if (buttons) {
btnOk.disabled = Boolean(error);
btnUndo.disabled = newValue === initialValue;
btnReset.disabled = !newValue;
}
}
if (e) {
e.preventDefault();
e.stopPropagation();
}
}
} }
/* exported showCodeMirrorPopup */ /* exported showCodeMirrorPopup */