Skip to content

Commit

Permalink
fix: handle non-parseable HTML inside parseable HTML
Browse files Browse the repository at this point in the history
Also made a change to avoid interim wrappers where possible in
situations where dangerouslySetInnerHTML is unavoidable.
  • Loading branch information
quantizor committed Apr 27, 2017
1 parent fafab42 commit 47c050b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 11 deletions.
29 changes: 18 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,16 +323,17 @@ function attributeValueToJSXPropValue(key, value) {
return value;
}

function isProcessableHTML(html) {
// ignore block-level elements
// ignore self-closing or non-content-bearing elements
return html.match(BLOCK_ELEMENT_REGEX) || html.match(SELF_CLOSING_ELEMENT_REGEX) ? false : true;
}

function coalesceInlineHTML(ast) {
function coalescer(node, index, siblings) {
if (node.type === 'html') {
// ignore block-level elements
if (BLOCK_ELEMENT_REGEX.test(node.value)) {
return;
}

// ignore self-closing or non-content-bearing elements
if (SELF_CLOSING_ELEMENT_REGEX.test(node.value)) {
if (!isProcessableHTML(node.value)) {
return;
}

Expand All @@ -347,7 +348,8 @@ function coalesceInlineHTML(ast) {

// where's the end tag?
while (end === undefined && i < siblings.length) {
if (siblings[i].type !== 'html') {
if ( siblings[i].type !== 'html'
|| (siblings[i].type === 'html' && !isProcessableHTML(siblings[i].value))) {
i += 1;
continue;
}
Expand Down Expand Up @@ -398,7 +400,7 @@ function coalesceInlineHTML(ast) {
}
};

return ast.children.forEach(coalescer);
ast.children.forEach(coalescer);
}

export function compiler(markdown, {overrides = {}} = {}) {
Expand Down Expand Up @@ -543,6 +545,11 @@ export function compiler(markdown, {overrides = {}} = {}) {

let props = {key, ...ast.props};

if (Array.isArray(ast.children) && ast.children.length === 1 && ast.children[0].type === 'html') {
props.dangerouslySetInnerHTML = {__html: ast.children[0].value};
ast.children = null;
}

const override = overrides[htmlNodeType];
if (override) {
if (override.component) {
Expand Down Expand Up @@ -606,9 +613,9 @@ export function compiler(markdown, {overrides = {}} = {}) {

let jsx = astToJSX(remarkAST);

// discard the root <div> node if there is only one valid initial child
// generally this is a paragraph
if (jsx.props.children.length === 1) {
// discard the root <div> node if there is only one valid initial child that doesn't
// contain dangerouslySetInnerHTML
if (jsx.props.children && jsx.props.children.length === 1) {
jsx = jsx.props.children[0];
}

Expand Down
9 changes: 9 additions & 0 deletions index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,15 @@ describe('markdown-to-jsx', () => {
expect($element.children[0].children[0].tagName).toBe('STRONG');
expect($element.children[0].children[0].textContent).toBe('code');
});

it('handles non-parsable html inside parsable html (regression)', () => {
const element = render(compiler('<a href="https://opencollective.com/react-dropzone/sponsor/0/website" target="_blank"><img src="https://opencollective.com/react-dropzone/sponsor/0/avatar.svg"></a>'));
const $element = dom(element);

expect($element.tagName).toBe('P');
expect($element.children[0].tagName).toBe('A');
expect($element.children[0].children[0].tagName).toBe('IMG');
});
});

describe('horizontal rules', () => {
Expand Down

0 comments on commit 47c050b

Please sign in to comment.