add buttons to hotkey input, reset on Del/BackSpace
This commit is contained in:
parent
ba7b55c23d
commit
6798114196
|
@ -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', {
|
||||||
|
|
|
@ -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 ************/
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
102
edit/util.js
102
edit/util.js
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user