mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-26 12:21:36 +03:00
✨ use markdown-it for markdown previews (#690)
✨ use markdown-it for markdown previews
no issue
- replaces SimpleMDE's default `marked` rendering with `markdown-it`
- add ember-browserify and markdown-it plugins
This commit is contained in:
parent
bbf5164b79
commit
4edebe9f1e
@ -4,6 +4,7 @@ import {assign} from 'ember-platform';
|
||||
import {copy} from 'ember-metal/utils';
|
||||
import {isEmpty} from 'ember-utils';
|
||||
import run from 'ember-runloop';
|
||||
import formatMarkdown from 'ghost-admin/utils/format-markdown';
|
||||
|
||||
const MOBILEDOC_VERSION = '0.3.1';
|
||||
|
||||
@ -57,11 +58,16 @@ export default Component.extend({
|
||||
_toolbar: null,
|
||||
_uploadedImageUrls: null,
|
||||
|
||||
// Ghost-Specific SimpleMDE toolbar config - allows us to create a bridge
|
||||
// between SimpleMDE buttons and Ember actions
|
||||
simpleMDEOptions: computed('options', function () {
|
||||
let options = this.get('options') || {};
|
||||
let defaultOptions = {
|
||||
// use our Showdown config with sanitization for previews
|
||||
previewRender(markdown) {
|
||||
return formatMarkdown(markdown);
|
||||
},
|
||||
|
||||
// Ghost-specific SimpleMDE toolbar config - allows us to create a
|
||||
// bridge between SimpleMDE buttons and Ember actions
|
||||
toolbar: [
|
||||
'bold', 'italic', 'heading', '|',
|
||||
'quote', 'unordered-list', 'ordered-list', '|',
|
||||
@ -109,11 +115,17 @@ export default Component.extend({
|
||||
title: 'Markdown Guide'
|
||||
}
|
||||
],
|
||||
|
||||
// disable shortcuts for side-by-side and fullscreen because they
|
||||
// trigger interal SimpleMDE methods that will result in broken
|
||||
// layouts
|
||||
shortcuts: {
|
||||
toggleFullScreen: null,
|
||||
togglePreview: null,
|
||||
toggleSideBySide: null
|
||||
},
|
||||
|
||||
// only include the number of words in the status bar
|
||||
status: ['words']
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
/**
|
||||
* Check if URL is allowed
|
||||
* URLs are allowed if they start with http://, https://, or /.
|
||||
* NOTE: # urls are not allowed as clicking them will break the editor when clicked
|
||||
*/
|
||||
let url = function (url) {
|
||||
url = url.toString().replace(/['"]+/g, '');
|
||||
|
47
ghost/admin/app/utils/format-markdown.js
Normal file
47
ghost/admin/app/utils/format-markdown.js
Normal file
@ -0,0 +1,47 @@
|
||||
/* global html_sanitize */
|
||||
import cajaSanitizers from './caja-sanitizers';
|
||||
import markdownit from 'npm:markdown-it';
|
||||
import markdownitFootnote from 'npm:markdown-it-footnote';
|
||||
import markdownitLazyHeaders from 'npm:markdown-it-lazy-headers';
|
||||
import markdownitMark from 'npm:markdown-it-mark';
|
||||
import markdownitNamedHeaders from 'npm:markdown-it-named-headers';
|
||||
|
||||
// eslint-disable-next-line new-cap
|
||||
let md = markdownit({
|
||||
html: true,
|
||||
breaks: true,
|
||||
linkify: true
|
||||
})
|
||||
.use(markdownitFootnote)
|
||||
.use(markdownitLazyHeaders)
|
||||
.use(markdownitMark)
|
||||
.use(markdownitNamedHeaders, {
|
||||
// match legacy Showdown IDs otherwise default is github style dasherized
|
||||
slugify(inputString, usedHeaders) {
|
||||
let slug = inputString.replace(/[^\w]/g, '').toLowerCase();
|
||||
if (usedHeaders[slug]) {
|
||||
usedHeaders[slug]++;
|
||||
slug += usedHeaders[slug];
|
||||
}
|
||||
return slug;
|
||||
}
|
||||
});
|
||||
|
||||
export default function formatMarkdown(_markdown) {
|
||||
let markdown = _markdown || '';
|
||||
let escapedhtml = '';
|
||||
|
||||
// convert markdown to HTML
|
||||
escapedhtml = md.render(markdown);
|
||||
|
||||
// replace script and iFrame
|
||||
escapedhtml = escapedhtml.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
|
||||
'<pre class="js-embed-placeholder">Embedded JavaScript</pre>');
|
||||
escapedhtml = escapedhtml.replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,
|
||||
'<pre class="iframe-embed-placeholder">Embedded iFrame</pre>');
|
||||
|
||||
// sanitize html
|
||||
escapedhtml = html_sanitize(escapedhtml, cajaSanitizers.url, cajaSanitizers.id);
|
||||
|
||||
return escapedhtml;
|
||||
}
|
@ -41,6 +41,7 @@
|
||||
"csscomb": "4.0.1",
|
||||
"cssnano": "3.10.0",
|
||||
"ember-ajax": "2.5.6",
|
||||
"ember-browserify": "1.1.13",
|
||||
"ember-cli": "2.13.1",
|
||||
"ember-cli-active-link-wrapper": "0.3.2",
|
||||
"ember-cli-app-version": "3.0.0",
|
||||
@ -97,6 +98,11 @@
|
||||
"liquid-fire": "0.27.3",
|
||||
"liquid-wormhole": "2.0.5",
|
||||
"loader.js": "4.4.0",
|
||||
"markdown-it": "8.3.1",
|
||||
"markdown-it-footnote": "3.0.1",
|
||||
"markdown-it-lazy-headers": "0.1.3",
|
||||
"markdown-it-mark": "2.0.0",
|
||||
"markdown-it-named-headers": "0.0.4",
|
||||
"matchdep": "1.0.1",
|
||||
"password-generator": "2.1.0",
|
||||
"postcss-color-function": "3.0.0",
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user