diff --git a/src/editor/index.js b/src/editor/index.js index 1620b6e02..8adefc03f 100644 --- a/src/editor/index.js +++ b/src/editor/index.js @@ -114,6 +114,7 @@ import $ from 'cash-dom'; import defaults from './config/config'; import EditorModel from './model/Editor'; import EditorView from './view/EditorView'; +import html from 'utils/html'; export default (config = {}) => { const c = { @@ -709,6 +710,19 @@ export default (config = {}) => { render() { editorView.render(); return editorView.el; - } + }, + + /** + * Print safe HTML by using ES6 tagged template strings. + * @param {Array} literals + * @param {Array} substs + * @returns {String} + * @example + * const unsafeStr = ''; + * const safeStr = 'Hello'; + * // Use `$${var}` to avoid escaping + * const strHtml = editor.html`Escaped ${unsafeStr}, unescaped $${safeStr}`; + */ + html }; }; diff --git a/src/utils/html.js b/src/utils/html.js new file mode 100644 index 000000000..d327f621f --- /dev/null +++ b/src/utils/html.js @@ -0,0 +1,30 @@ +import { escape } from './mixins'; + +/** + * Safe ES6 tagged template strings + * @param {Array} literals + * @param {Array} substs + * @returns {String} + * @example + * const str = 'Hello'; + * const strHtml = html`Escaped ${str}, unescaped $${str}`; + */ +export default function html(literals, ...substs) { + const { raw } = literals; + + return raw.reduce((acc, lit, i) => { + let subst = substs[i - 1]; + const last = raw[i - 1]; + + if (Array.isArray(subst)) { + subst = subst.join(''); + } else if (last && last.slice(-1) === '$') { + // If the interpolation is preceded by a dollar sign, it won't be escaped + acc = acc.slice(0, -1); + } else { + subst = escape(subst); + } + + return acc + subst + lit; + }); +}