Skip to content

Commit

Permalink
fix(editor): Render checkboxes in markdown (#9549)
Browse files Browse the repository at this point in the history
  • Loading branch information
MiloradFilipovic committed May 30, 2024
1 parent a221215 commit 47d7741
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,18 @@ Markdown.args = {
},
],
};

const TemplateWithCheckboxes: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nMarkdown,
},
template: '<n8n-markdown v-bind="args"></n8n-markdown>',
});

export const WithCheckboxes = TemplateWithCheckboxes.bind({});
WithCheckboxes.args = {
content: '__TODO__\n- [ ] Buy milk\n- [X] Buy socks\n',
loading: false,
};
15 changes: 14 additions & 1 deletion packages/design-system/src/components/N8nMarkdown/Markdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import Markdown from 'markdown-it';
import markdownLink from 'markdown-it-link-attributes';
import markdownEmoji from 'markdown-it-emoji';
import markdownTaskLists from 'markdown-it-task-lists';
import xss, { friendlyAttrValue } from 'xss';
import xss, { friendlyAttrValue, whiteList } from 'xss';
import N8nLoading from '../N8nLoading';
import { escapeMarkdown } from '../../utils/markdown';
Expand Down Expand Up @@ -72,6 +72,7 @@ const props = withDefaults(defineProps<MarkdownProps>(), {
},
},
tasklists: {
enabled: true,
label: true,
labelAfter: true,
},
Expand All @@ -84,6 +85,11 @@ const md = new Markdown(options.markdown)
.use(markdownEmoji)
.use(markdownTaskLists, options.tasklists);
const xssWhiteList = {
...whiteList,
label: ['class', 'for'],
};
const htmlContent = computed(() => {
if (!props.content) {
return '';
Expand Down Expand Up @@ -130,6 +136,13 @@ const htmlContent = computed(() => {
}
// return nothing, keep tag
},
onIgnoreTag(tag, tagHTML) {
// Allow checkboxes
if (tag === 'input' && tagHTML.includes('type="checkbox"')) {
return tagHTML;
}
},
whiteList: xssWhiteList,
});
return safeHtml;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { render } from '@testing-library/vue';
import N8nMarkdown from '../Markdown.vue';

describe('components', () => {
describe('N8nMarkdown', () => {
it('should render unchecked checkboxes', () => {
const wrapper = render(N8nMarkdown, {
props: {
content: '__TODO__\n- [ ] Buy milk\n- [ ] Buy socks\n',
},
});
const checkboxes = wrapper.getAllByRole('checkbox');
expect(checkboxes).toHaveLength(2);
checkboxes.forEach((checkbox) => {
expect(checkbox).not.toBeChecked();
});
});
it('should render checked checkboxes', () => {
const wrapper = render(N8nMarkdown, {
props: {
content: '__TODO__\n- [X] Buy milk\n- [X] Buy socks\n',
},
});
const checkboxes = wrapper.getAllByRole('checkbox');
expect(checkboxes).toHaveLength(2);
checkboxes.forEach((checkbox) => {
expect(checkbox).toBeChecked();
});
});
it('should render inputs as plain text', () => {
const wrapper = render(N8nMarkdown, {
props: {
content:
'__TODO__\n- [X] Buy milk\n- <input type="text" data-testid="text-input" value="Something"/>\n',
},
});
const checkboxes = wrapper.getAllByRole('checkbox');
expect(checkboxes).toHaveLength(1);
expect(wrapper.queryByTestId('text-input')).toBeNull();
expect(wrapper.html()).toContain(
'&lt;input type=“text” data-testid=“text-input” value=“Something”/&gt;',
);
});
});
});

0 comments on commit 47d7741

Please sign in to comment.