diff --git a/ui/component/common/form-components/form-field.jsx b/ui/component/common/form-components/form-field.jsx index a92ee35bc..3662b17ac 100644 --- a/ui/component/common/form-components/form-field.jsx +++ b/ui/component/common/form-components/form-field.jsx @@ -18,7 +18,7 @@ type Props = { error?: string | boolean, helper?: string | React$Node, type?: string, - onChange?: any => any, + onChange?: (any) => any, defaultValue?: string | number, placeholder?: string | number, children?: React$Node, @@ -37,7 +37,7 @@ type Props = { min?: number, max?: number, quickActionLabel?: string, - quickActionHandler?: any => any, + quickActionHandler?: (any) => any, }; export class FormField extends React.PureComponent { @@ -147,7 +147,7 @@ export class FormField extends React.PureComponent { contextmenu: openEditorMenu, }; - const getInstance = editor => { + const getInstance = (editor) => { // SimpleMDE max char check editor.codemirror.on('beforeChange', (instance, changes) => { if (textAreaMaxLength && changes.update) { @@ -163,6 +163,44 @@ export class FormField extends React.PureComponent { } } }); + + // "Create Link (Ctrl-K)": highlight URL instead of label: + editor.codemirror.on('changes', (instance, changes) => { + try { + // Grab the last change from the buffered list. I assume the + // buffered one ('changes', instead of 'change') is more efficient, + // and that "Create Link" will always end up last in the list. + const lastChange = changes[changes.length - 1]; + if (lastChange.origin === '+input') { + // https://github.com/Ionaru/easy-markdown-editor/blob/8fa54c496f98621d5f45f57577ce630bee8c41ee/src/js/easymde.js#L765 + const EASYMDE_URL_PLACEHOLDER = '(https://)'; + + // The URL placeholder is always placed last, so just look at the + // last text in the array to also cover the multi-line case: + const urlLineText = lastChange.text[lastChange.text.length - 1]; + + if (urlLineText.endsWith(EASYMDE_URL_PLACEHOLDER) && urlLineText !== '[]' + EASYMDE_URL_PLACEHOLDER) { + const from = lastChange.from; + const to = lastChange.to; + const isSelectionMultiline = lastChange.text.length > 1; + const baseIndex = isSelectionMultiline ? 0 : from.ch; + + // Everything works fine for the [Ctrl-K] case, but for the + // [Button] case, this handler happens before the original + // code, thus our change got wiped out. + // Add a small delay to handle that case. + setTimeout(() => { + instance.setSelection( + { line: to.line, ch: baseIndex + urlLineText.lastIndexOf('(') + 1 }, + { line: to.line, ch: baseIndex + urlLineText.lastIndexOf(')') } + ); + }, 25); + } + } + } catch (err) { + // Do nothing (revert to original behavior) + } + }); }; // Ideally, the character count should (and can) be appended to the