Skip to content

Commit

Permalink
fix: handle self-closing HTML inside inline 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 96c309d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 11 deletions.
27 changes: 16 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,16 +323,16 @@ function attributeValueToJSXPropValue(key, value) {
return value;
}

function isCoalesceableHTML(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 (!isCoalesceableHTML(node.value)) {
return;
}

Expand All @@ -347,7 +347,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' && !isCoalesceableHTML(siblings[i].value))) {
i += 1;
continue;
}
Expand Down Expand Up @@ -398,7 +399,7 @@ function coalesceInlineHTML(ast) {
}
};

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

export function compiler(markdown, {overrides = {}} = {}) {
Expand Down Expand Up @@ -543,6 +544,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 @@ -607,8 +613,7 @@ 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) {
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 self-closing 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 96c309d

Please sign in to comment.