diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..662f9240 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "conventionalCommits.scopes": [ + "htmlblock" + ] +} \ No newline at end of file diff --git a/README.md b/README.md index f653183d..431aa437 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,64 @@ var md = new Remarkable({ // Highlighter function. Should return escaped HTML, // or '' if the source string is not changed - highlight: function (/*str, lang*/) { return ''; } + highlight: function (/*str, lang*/) { return ''; }, + + // Allow / Disallow html tags that are available for parsing HTML + htmlAllowedTags: [ + /^my-.*/, + 'my-web-component', // Custom-tag + + 'article', + 'aside', + 'button', + 'blockquote', + 'body', + 'canvas', + 'caption', + 'col', + 'colgroup', + 'dd', + 'div', + 'dl', + 'dt', + 'embed', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'header', + 'hgroup', + 'hr', + 'iframe', + 'li', + 'map', + 'object', + 'ol', + 'output', + 'p', + 'pre', + 'progress', + 'script', + 'section', + 'style', + 'table', + 'tbody', + 'td', + 'textarea', + 'tfoot', + 'th', + 'tr', + 'thead', + 'ul', + 'video' + ] }); console.log(md.render('# Remarkable rulezz!')); diff --git a/lib/rules_block/htmlblock.js b/lib/rules_block/htmlblock.js index 57f66af4..d5094581 100644 --- a/lib/rules_block/htmlblock.js +++ b/lib/rules_block/htmlblock.js @@ -1,10 +1,10 @@ // HTML block -import block_names from '../common/html_blocks'; +import html_blocks from '../common/html_blocks'; -var HTML_TAG_OPEN_RE = /^<([a-zA-Z]{1,15})[\s\/>]/; -var HTML_TAG_CLOSE_RE = /^<\/([a-zA-Z]{1,15})[\s>]/; +var HTML_TAG_OPEN_RE = /^<([a-zA-Z_-]{1,15})[\s\/>]/; +var HTML_TAG_CLOSE_RE = /^<\/([a-zA-Z_-]{1,15})[\s>]/; function isLetter(ch) { /*eslint no-bitwise:0*/ @@ -20,9 +20,19 @@ export default function htmlblock(state, startLine, endLine, silent) { pos += shift; + let allowedBlocks = html_blocks; + if (!state.options.html) { return false; } - if (shift > 3 || pos + 2 >= max) { return false; } + if (!Array.isArray(allowedBlocks)) { + allowedBlocks = Object.keys(allowedBlocks) + } + + if (Array.isArray(state.options.htmlAllowedTags)) { + allowedBlocks = state.options.htmlAllowedTags; + } + + if (shift > 3 + state.blkIndent || pos + 2 >= max) { return false; } if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; } @@ -44,8 +54,19 @@ export default function htmlblock(state, startLine, endLine, silent) { match = state.src.slice(pos, max).match(HTML_TAG_OPEN_RE); if (!match) { return false; } } + // Make sure tag name is valid - if (block_names[match[1].toLowerCase()] !== true) { return false; } + const tagToCheck = match[1].toLowerCase(); + if (!allowedBlocks.includes(tagToCheck)) { + const regExpressions = allowedBlocks + .filter(possibleExpression => typeof possibleExpression !== 'string') + .filter(possibleExpression => !!possibleExpression.test); + + if (!regExpressions.some(x => x.test(tagToCheck))) { + return false; + } + } + if (silent) { return true; } } else {