0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00
ghost/core/server/apps/default-cards/cards/markdown.js
Ryan McCarvill 957f51e677 🐝 Allow unbalanced HTML in markdown card. (#8320)
no issue

The simpledom interpreter that the Mobiledoc DOM renderer uses does not allow for unbalanced or incorrect HTML such as that which is entered by a user.

This PR adds a step where the HTML is sanitised and balanced before being passed to simpledom.

- use latest jsdom (+pin version), update yarn.lock, add comments
- don't use node-4 incompatible shorthand method definition
- grab <body> content rather than document content
- update markdown card specs to match markdown-it behaviour
- revert to jsdom 9.12.0 for node 4.x support, close window to free memory
- moved 3rd party libs into render function
2017-05-23 16:15:32 +02:00

46 lines
1.9 KiB
JavaScript

var markdownConverter = require('../../../utils/markdown-converter');
module.exports = {
name: 'card-markdown',
type: 'dom',
render: function (opts) {
var SimpleDom = require('simple-dom'),
tokenizer = require('simple-html-tokenizer').tokenize,
jsdom = require('jsdom').jsdom,
html, doc, parser, sanitizedHTML;
// markdown can be autosaved at any point by the client, even when
// writing HTML so you can end up with unbalanced HTML elements
//
// mobiledoc uses simple-dom to build a DOM object. simple-dom is
// purposefully very basic and only designed to handle valid HTML,
// if it's fed unbalanced or invalid HTML it will throw an error.
//
// to work around the possibility of having invalid HTML we first
// pass the HTML through jsdom which seeks to fully emulate the
// WHATWG DOM/HTML standards including the ability to handle
// unbalanced HTML in the same way a browser does
html = markdownConverter.render(opts.payload.markdown || '');
doc = jsdom(html, {
features: {
FetchExternalResources: false,
ProcessExternalResources: false
}
});
// grab the rendered + sanitized body HTML
sanitizedHTML = doc.body.innerHTML;
// free up memory by closing the jsdom "window"
doc.defaultView.close();
parser = new SimpleDom.HTMLParser(tokenizer, opts.env.dom, SimpleDom.voidMap);
// generate a new SimpleDom object from the sanitzed HTML
return parser.parse(''
+ '<div class="kg-card-markdown">'
+ sanitizedHTML
+ '</div>'
);
}
};