From 33951053175457320371714d7bc6aa5513f8f2c1 Mon Sep 17 00:00:00 2001 From: Evan Jacobs Date: Mon, 26 Sep 2016 14:10:42 -0400 Subject: [PATCH 1/2] Override support for pre & code elements generated in astToJSX --- index.js | 22 +++++++++---- index.spec.js | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index 6ca85ab8..7b34ec51 100644 --- a/index.js +++ b/index.js @@ -412,12 +412,22 @@ export default function markdownToJSX(markdown, {overrides = {}} = {}) { const key = index || '0'; if (ast.type === 'code' && ast.value) { - return ( -
-                    
-                        {ast.value}
-                    
-                
+ const preProps = get(overrides, 'pre.props', {}); + const codeProps = get(overrides, 'code.props', {}); + + preProps.key = key; + codeProps.className = codeProps.className + ? `${codeProps.className} lang-${ast.lang}` + : `lang-${ast.lang}`; + + return React.createElement( + get(overrides, 'pre.component', 'pre'), + preProps, + React.createElement( + get(overrides, 'code.component', 'code'), + codeProps, + ast.value + ), ); } /* Refers to fenced blocks, need to create a pre:code nested structure */ diff --git a/index.spec.js b/index.spec.js index 7eb6b645..c0dee53a 100644 --- a/index.spec.js +++ b/index.spec.js @@ -695,5 +695,93 @@ describe('markdown-to-jsx', () => { expect($element.className).toBe('abc'); expect($element.textContent).toBe('Hello.'); }); + + it('should add props to pre & code tags if supplied', () => { + const element = render( + converter(` + \`\`\` + foo + \`\`\` + `, { + overrides: { + code: { + props: { + 'data-foo': 'bar', + }, + }, + + pre: { + props: { + className: 'abc', + }, + }, + }, + }) + ); + + const $element = dom(element); + + expect($element.tagName).toBe('PRE'); + expect($element.className).toBe('abc'); + expect($element.textContent).toContain('foo'); + expect($element.children[0].tagName).toBe('CODE'); + expect($element.children[0].getAttribute('data-foo')).toBe('bar'); + }); + + it('should substitute pre & code tags if supplied with an override component', () => { + class OverridenPre extends React.Component { + render() { + const {children, ...props} = this.props; + + return ( +
{children}
+ ); + } + } + + class OverridenCode extends React.Component { + render() { + const {children, ...props} = this.props; + + return ( + {children} + ); + } + } + + const element = render( + converter(` + \`\`\` + foo + \`\`\` + `, { + overrides: { + code: { + component: OverridenCode, + props: { + 'data-foo': 'bar', + }, + }, + + pre: { + component: OverridenPre, + props: { + className: 'abc', + }, + }, + }, + }) + ); + + const $element = dom(element); + + expect($element.tagName).toBe('PRE'); + expect($element.className).toBe('abc'); + expect($element.getAttribute('data-bar')).toBe('baz'); + expect($element.textContent).toContain('foo'); + expect($element.children[0].tagName).toBe('CODE'); + expect($element.children[0].getAttribute('data-foo')).toBe('bar'); + expect($element.children[0].getAttribute('data-baz')).toBe('fizz'); + }); }); }); From 25f70a6d6e78a88dbc0bb8bb05356fb88eecced2 Mon Sep 17 00:00:00 2001 From: Evan Jacobs Date: Mon, 26 Sep 2016 14:22:14 -0400 Subject: [PATCH 2/2] Allow overrides for GFM task list items & associated checkboxes --- README.md | 1 + index.js | 26 ++++++++++++++++++-------- index.spec.js | 20 ++++++++++++++++++-- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d22431ce..a6e64615 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ Depending on the type of element, there are some props that must be preserved to - `a`: `title`, `href` - `img`: `title`, `alt`, `src` +- `input[type="checkbox"]`: `checked`, `readonly` (specifically, the one rendered by a GFM task list) - `ol`: `start` - `td`: `style` - `th`: `style` diff --git a/index.js b/index.js index 7b34ec51..04c37b61 100644 --- a/index.js +++ b/index.js @@ -446,14 +446,24 @@ export default function markdownToJSX(markdown, {overrides = {}} = {}) { if (ast.type === 'listItem') { if (ast.checked === true || ast.checked === false) { - return ( -
  • - - {ast.children.map(astToJSX)} -
  • + const liProps = get(overrides, 'li.props', {}); + + liProps.key = key; + + const inputProps = get(overrides, 'input.props', {}); + + inputProps.key = 'checkbox'; + inputProps.type = 'checkbox'; + inputProps.checked = ast.checked; + inputProps.readOnly = true; + + return React.createElement( + get(overrides, 'li.component', 'li'), + liProps, + [ + React.createElement(get(overrides, 'input.component', 'input'), inputProps), + ast.children.map(astToJSX), + ], ); } /* gfm task list, need to add a checkbox */ } diff --git a/index.spec.js b/index.spec.js index c0dee53a..1e43827d 100644 --- a/index.spec.js +++ b/index.spec.js @@ -403,13 +403,13 @@ describe('markdown-to-jsx', () => { expect(checkbox.parentNode.textContent).toBe('foo'); }); - it('should disable the checkboxes', () => { + it('should mark the checkboxes as readonly', () => { const element = render(converter('- [x] foo')); const $element = dom(element); const checkbox = $element.querySelector('ul li input'); expect(checkbox).not.toBe(null); - expect(checkbox.disabled).toBe(true); + expect(checkbox.readOnly).toBe(true); }); }); @@ -783,5 +783,21 @@ describe('markdown-to-jsx', () => { expect($element.children[0].getAttribute('data-foo')).toBe('bar'); expect($element.children[0].getAttribute('data-baz')).toBe('fizz'); }); + + it('should be able to override gfm task list items', () => { + const element = render(converter('- [ ] foo', {overrides: {li: {props: {className: 'foo'}}}})); + const $element = dom(element).querySelector('li'); + + expect($element).not.toBe(null); + expect($element.className).toContain('foo'); + }); + + it('should be able to override gfm task list item checkboxes', () => { + const element = render(converter('- [ ] foo', {overrides: {input: {props: {className: 'foo'}}}})); + const $element = dom(element).querySelector('input'); + + expect($element).not.toBe(null); + expect($element.className).toContain('foo'); + }); }); });