Koenig - Allow heading levels to be changed via markdown expansion

refs https://github.com/TryGhost/Ghost/issues/9623
- disable the default mobiledoc-kit heading text expansion and replace with our own that matches heading markdown at the beginning of existing text and will change the heading level of the existing text
This commit is contained in:
Kevin Ansfield 2018-05-14 18:29:54 +01:00
parent 1b02a63848
commit 8e2a622169

View File

@ -9,43 +9,41 @@ import {run} from '@ember/runloop';
// https://github.com/bustlelabs/mobiledoc-kit#responding-to-text-input // https://github.com/bustlelabs/mobiledoc-kit#responding-to-text-input
export default function (editor, koenig) { export default function (editor, koenig) {
// We don't want to run all our content rules on every text entry event, /* block level markdown ------------------------------------------------- */
// instead we check to see if this text entry event could match a content
// rule, and only then run the rules. Right now we only want to match
// content ending with *, _, ), ~, and `. This could increase as we support
// more markdown.
editor.unregisterTextInputHandler('heading');
editor.onTextInput({ editor.onTextInput({
name: 'inline_markdown', name: 'md_heading',
match: /[*_)~`]$/, match: /^(#{1,6}) /,
run(editor, matches) { run(editor, matches) {
let hashes = matches[1];
let headingTag = `h${hashes.length}`;
let {range} = editor;
let text = editor.range.head.section.textUntil(editor.range.head); let text = editor.range.head.section.textUntil(editor.range.head);
switch (matches[0]) { // we don't want to convert to a heading if the user has not just
case '*': // finished typing the markdown (eg, they've made a previous
matchStrongStar(editor, text); // heading expansion then Cmd-Z'ed it to get the text back then
matchEmStar(editor, text); // starts typing at the end of the heading)
break; if (text !== matches[0]) {
case '_': return;
matchStrongUnderscore(editor, text);
matchEmUnderscore(editor, text);
break;
case ')':
matchLink(editor, text);
matchImage(editor, text);
break;
case '~':
matchStrikethrough(editor, text);
break;
case '`':
matchCode(editor, text);
break;
} }
editor.run((postEditor) => {
range = range.extend(-(matches[0].length));
let position = postEditor.deleteRange(range);
postEditor.setRange(position);
// skip toggle if we already have the same heading level
if (editor.activeSection.tagName === headingTag) {
return;
}
postEditor.toggleSection(headingTag);
});
} }
}); });
/* block level markdown ------------------------------------------------- */
// mobiledoc-kit has `* ` already built-in so we only need to add `- ` // mobiledoc-kit has `* ` already built-in so we only need to add `- `
editor.onTextInput({ editor.onTextInput({
name: 'md_ul', name: 'md_ul',
@ -85,6 +83,41 @@ export default function (editor, koenig) {
/* inline markdown ------------------------------------------------------ */ /* inline markdown ------------------------------------------------------ */
// We don't want to run all our content rules on every text entry event,
// instead we check to see if this text entry event could match a content
// rule, and only then run the rules. Right now we only want to match
// content ending with *, _, ), ~, and `. This could increase as we support
// more markdown.
editor.onTextInput({
name: 'inline_markdown',
match: /[*_)~`]$/,
run(editor, matches) {
let text = editor.range.head.section.textUntil(editor.range.head);
switch (matches[0]) {
case '*':
matchStrongStar(editor, text);
matchEmStar(editor, text);
break;
case '_':
matchStrongUnderscore(editor, text);
matchEmUnderscore(editor, text);
break;
case ')':
matchLink(editor, text);
matchImage(editor, text);
break;
case '~':
matchStrikethrough(editor, text);
break;
case '`':
matchCode(editor, text);
break;
}
}
});
// --\s = en dash // --\s = en dash
// ---. = em dash — // ---. = em dash —
// separate to the grouped replacement functions because we're matching on // separate to the grouped replacement functions because we're matching on