Ghost/ghost/admin/utils/codemirror-shortcuts.js
Matt Enlow 52118c16e3 Implement Markdown Shortcuts
Closes #2984, #3020
Ref #1463, #3019

 #### Shortcut Values
Shortcut values can now be either strings (as before) or objects like
{action:string, options:hash}.
 #### Markdown shortcuts added
- 'ctrl+alt+u' strkethrough
- 'ctrl+alt+1' h1
- 'ctrl+alt+2' h2
- 'ctrl+alt+3' h3
- 'ctrl+alt+4' h4
- 'ctrl+alt+5' h5
- 'ctrl+alt+6' h6
- 'ctrl+shift+i' image
- 'ctrl/command+k' link
- 'ctrl+l' list

Left behind commented out stubs for additional markdown shortcuts.

 #### Editor Controllers (New and Edit)
- Moved shared init function into editor-base-controller.
- Removed MarkerManager mixin from editor controllers as it's included in
  the base.
2014-06-21 15:10:46 -06:00

131 lines
4.1 KiB
JavaScript

/* global CodeMirror, moment */
/** Set up a shortcut function to be called via router actions.
* See editor-route-base
*/
//Used for simple, noncomputational replace-and-go! shortcuts.
// See default case in shortcut function below.
CodeMirror.prototype.simpleShortcutSyntax = {
bold: '**$1**',
italic: '*$1*',
strike: '~~$1~~',
code: '`$1`',
link: '[$1](http://)',
image: '![$1](http://)',
blockquote: '> $1'
};
CodeMirror.prototype.shortcut = function (type) {
var text = this.getSelection(),
cursor = this.getCursor(),
line = this.getLine(cursor.line),
fromLineStart = {line: cursor.line, ch: 0},
md, letterCount, textIndex, position;
switch (type) {
case 'h1':
this.replaceRange('# ' + line, fromLineStart);
this.setCursor(cursor.line, cursor.ch + 2);
return;
case 'h2':
this.replaceRange('## ' + line, fromLineStart);
this.setCursor(cursor.line, cursor.ch + 3);
return;
case 'h3':
this.replaceRange('### ' + line, fromLineStart);
this.setCursor(cursor.line, cursor.ch + 4);
return;
case 'h4':
this.replaceRange('#### ' + line, fromLineStart);
this.setCursor(cursor.line, cursor.ch + 5);
return;
case 'h5':
this.replaceRange('##### ' + line, fromLineStart);
this.setCursor(cursor.line, cursor.ch + 6);
return;
case 'h6':
this.replaceRange('###### ' + line, fromLineStart);
this.setCursor(cursor.line, cursor.ch + 7);
return;
case 'link':
md = this.simpleShortcutSyntax.link.replace('$1', text);
this.replaceSelection(md, 'end');
if (!text) {
this.setCursor(cursor.line, cursor.ch + 1);
} else {
textIndex = line.indexOf(text, cursor.ch - text.length);
position = textIndex + md.length - 1;
this.setSelection({
line: cursor.line,
ch: position - 7
}, {
line: cursor.line,
ch: position
});
}
return;
case 'image':
md = this.simpleShortcutSyntax.image.replace('$1', text);
if (line !== '') {
md = '\n\n' + md;
}
this.replaceSelection(md, 'end');
cursor = this.getCursor();
this.setSelection({line: cursor.line, ch: cursor.ch - 8}, {line: cursor.line, ch: cursor.ch - 1});
return;
case 'list':
md = text.replace(/^(\s*)(\w\W*)/gm, '$1* $2');
this.replaceSelection(md, 'end');
return;
case 'currentDate':
md = moment(new Date()).format('D MMMM YYYY');
this.replaceSelection(md, 'end');
return;
/** @TODO
case 'uppercase':
md = text.toLocaleUpperCase();
break;
case 'lowercase':
md = text.toLocaleLowerCase();
break;
case 'titlecase':
md = text.toTitleCase();
break;
case 'selectword':
word = this.getTokenAt(cursor);
if (!/\w$/g.test(word.string)) {
this.setSelection({line: cursor.line, ch: word.start}, {line: cursor.line, ch: word.end - 1});
} else {
this.setSelection({line: cursor.line, ch: word.start}, {line: cursor.line, ch: word.end});
}
break;
case 'copyHTML':
converter = new Showdown.converter();
if (text) {
md = converter.makeHtml(text);
} else {
md = converter.makeHtml(this.getValue());
}
$(".modal-copyToHTML-content").text(md).selectText();
break;
case 'newLine':
if (line !== "") {
this.replaceRange(line + "\n\n", fromLineStart);
}
break;
*/
default:
if (this.simpleShortcutSyntax[type]) {
md = this.simpleShortcutSyntax[type].replace('$1', text);
}
}
if (md) {
this.replaceSelection(md, 'end');
if (!text) {
letterCount = md.length;
this.setCursor({
line: cursor.line,
ch: cursor.ch + (letterCount / 2)
});
}
}
};