* rough starting point, roving tabindex in toolbar, bold and italic buttons * refactor, add link * add ul * add ordered list * core formatters in place, wip * overflow options * add keyboard shortcuts * tidy up some dodgy classes * add mocks for runtime in test and storybook, use correct modifier key for tooltip * style tweaks * refactor tooltips * add markdown formatters tests * add tests for toolbar component, fix mistake in overflow menu tooltips * undo change no longer needed to button * fix issue accessing runtime in formatters file * only show darkened buttons and tooltips when focus-visible is true * mobile view * fix for responsive buttons & roving tabindex * tweaks from PR review * update cursor position on link insertion * add a new line after block selection formatting * align icons in center * tidy up overflow menu listeners * small refactors * test for new text area util * tidy up new lines after syntaxes * fix logic in cursor offsets for links * prevent scroll jumps after inserting syntax * some style tweaks * insert level 2 heading with new lines above and below * update icons * use margin instead of gap
258 lines
6.9 KiB
JavaScript
258 lines
6.9 KiB
JavaScript
import {
|
|
coreSyntaxFormatters,
|
|
secondarySyntaxFormatters,
|
|
} from '../markdownSyntaxFormatters';
|
|
|
|
describe('markdownSntaxFormatters', () => {
|
|
const exampleTextSelection = 'selection';
|
|
|
|
it('formats bold text', () => {
|
|
expect(
|
|
coreSyntaxFormatters['bold'].getFormatting(exampleTextSelection),
|
|
).toEqual({
|
|
formattedText: '**selection**',
|
|
cursorOffsetStart: 2,
|
|
cursorOffsetEnd: 2,
|
|
});
|
|
});
|
|
|
|
it('formats italic text', () => {
|
|
expect(
|
|
coreSyntaxFormatters['italic'].getFormatting(exampleTextSelection),
|
|
).toEqual({
|
|
formattedText: '_selection_',
|
|
cursorOffsetStart: 1,
|
|
cursorOffsetEnd: 1,
|
|
});
|
|
});
|
|
|
|
it('formats a link with an empty selection', () => {
|
|
expect(coreSyntaxFormatters['link'].getFormatting('')).toEqual({
|
|
formattedText: '[](url)',
|
|
cursorOffsetStart: 1,
|
|
cursorOffsetEnd: 1,
|
|
});
|
|
});
|
|
|
|
it('formats a link with a non-URL selection', () => {
|
|
expect(
|
|
coreSyntaxFormatters['link'].getFormatting(exampleTextSelection),
|
|
).toEqual({
|
|
formattedText: '[selection](url)',
|
|
cursorOffsetStart: 12,
|
|
cursorOffsetEnd: 6,
|
|
});
|
|
});
|
|
|
|
it('formats a link with an http URL selection', () => {
|
|
expect(
|
|
coreSyntaxFormatters['link'].getFormatting('http://myurl.com'),
|
|
).toEqual({
|
|
formattedText: '[](http://myurl.com)',
|
|
cursorOffsetStart: 1,
|
|
cursorOffsetEnd: -15,
|
|
});
|
|
});
|
|
|
|
it('formats a link with an https URL selection', () => {
|
|
expect(
|
|
coreSyntaxFormatters['link'].getFormatting('https://myurl.com'),
|
|
).toEqual({
|
|
formattedText: '[](https://myurl.com)',
|
|
cursorOffsetStart: 1,
|
|
cursorOffsetEnd: -16,
|
|
});
|
|
});
|
|
|
|
it('formats an unordered list from an empty selection', () => {
|
|
expect(coreSyntaxFormatters['unorderedList'].getFormatting('')).toEqual({
|
|
formattedText: '\n- ',
|
|
cursorOffsetStart: 3,
|
|
cursorOffsetEnd: 3,
|
|
});
|
|
});
|
|
|
|
it('formats an unordered list from a single line selection', () => {
|
|
expect(
|
|
coreSyntaxFormatters['unorderedList'].getFormatting(exampleTextSelection),
|
|
).toEqual({
|
|
formattedText: '\n- selection\n',
|
|
cursorOffsetStart: 1,
|
|
cursorOffsetEnd: 4,
|
|
});
|
|
});
|
|
|
|
it('formats an unordered list from a multi-line selection', () => {
|
|
expect(
|
|
coreSyntaxFormatters['unorderedList'].getFormatting('one\ntwo'),
|
|
).toEqual({
|
|
formattedText: '\n- one\n- two\n',
|
|
cursorOffsetStart: 1,
|
|
cursorOffsetEnd: 6,
|
|
});
|
|
});
|
|
|
|
it('formats an ordered list from an empty selection', () => {
|
|
expect(coreSyntaxFormatters['orderedList'].getFormatting('')).toEqual({
|
|
formattedText: '\n1. ',
|
|
cursorOffsetStart: 4,
|
|
cursorOffsetEnd: 4,
|
|
});
|
|
});
|
|
|
|
it('formats an ordered list from a single line selection', () => {
|
|
expect(
|
|
coreSyntaxFormatters['orderedList'].getFormatting(exampleTextSelection),
|
|
).toEqual({
|
|
formattedText: '\n1. selection\n',
|
|
cursorOffsetStart: 1,
|
|
cursorOffsetEnd: 5,
|
|
});
|
|
});
|
|
|
|
it('formats an ordered list from a multi-line selection', () => {
|
|
expect(
|
|
coreSyntaxFormatters['orderedList'].getFormatting('one\ntwo'),
|
|
).toEqual({
|
|
formattedText: '\n1. one\n2. two\n',
|
|
cursorOffsetStart: 1,
|
|
cursorOffsetEnd: 8,
|
|
});
|
|
});
|
|
|
|
it('Formats a heading from an empty selection', () => {
|
|
expect(coreSyntaxFormatters['heading'].getFormatting('')).toEqual({
|
|
formattedText: '\n## \n',
|
|
cursorOffsetStart: 4,
|
|
cursorOffsetEnd: 4,
|
|
});
|
|
});
|
|
|
|
it('Formats a heading from a selection with no heading level', () => {
|
|
expect(
|
|
coreSyntaxFormatters['heading'].getFormatting(exampleTextSelection),
|
|
).toEqual({
|
|
formattedText: '\n## selection\n',
|
|
cursorOffsetStart: 4,
|
|
cursorOffsetEnd: 4,
|
|
});
|
|
});
|
|
|
|
it('Formats a heading from a selection with a heading level 2', () => {
|
|
expect(
|
|
coreSyntaxFormatters['heading'].getFormatting('## selection'),
|
|
).toEqual({
|
|
formattedText: '### selection',
|
|
cursorOffsetStart: 4,
|
|
cursorOffsetEnd: 1,
|
|
});
|
|
});
|
|
|
|
it('Formats a heading from a selection with a heading level 3', () => {
|
|
expect(
|
|
coreSyntaxFormatters['heading'].getFormatting('### selection'),
|
|
).toEqual({
|
|
formattedText: '#### selection',
|
|
cursorOffsetStart: 5,
|
|
cursorOffsetEnd: 1,
|
|
});
|
|
});
|
|
|
|
it('Formats a heading from a selection with a heading level 4 by returning same selection', () => {
|
|
expect(
|
|
coreSyntaxFormatters['heading'].getFormatting('#### selection'),
|
|
).toEqual({
|
|
formattedText: '#### selection',
|
|
cursorOffsetStart: 5,
|
|
cursorOffsetEnd: 0,
|
|
});
|
|
});
|
|
|
|
it('formats a quote with empty selection', () => {
|
|
expect(coreSyntaxFormatters['quote'].getFormatting('')).toEqual({
|
|
formattedText: '\n> \n',
|
|
cursorOffsetStart: 3,
|
|
cursorOffsetEnd: 3,
|
|
});
|
|
});
|
|
|
|
it('formats a quote on a single-line selection', () => {
|
|
expect(
|
|
coreSyntaxFormatters['quote'].getFormatting(exampleTextSelection),
|
|
).toEqual({
|
|
formattedText: '\n> selection\n',
|
|
cursorOffsetStart: 3,
|
|
cursorOffsetEnd: 4,
|
|
});
|
|
});
|
|
|
|
it('formats a quote on a multi-line selection', () => {
|
|
expect(coreSyntaxFormatters['quote'].getFormatting('one\ntwo')).toEqual({
|
|
formattedText: '\n> one\n> two\n',
|
|
cursorOffsetStart: 3,
|
|
cursorOffsetEnd: 6,
|
|
});
|
|
});
|
|
|
|
it('formats inline code', () => {
|
|
expect(
|
|
coreSyntaxFormatters['code'].getFormatting(exampleTextSelection),
|
|
).toEqual({
|
|
formattedText: '`selection`',
|
|
cursorOffsetStart: 1,
|
|
cursorOffsetEnd: 1,
|
|
});
|
|
});
|
|
|
|
it('formats a code block', () => {
|
|
expect(
|
|
coreSyntaxFormatters['codeBlock'].getFormatting(exampleTextSelection),
|
|
).toEqual({
|
|
formattedText: '\n```\nselection\n```\n',
|
|
cursorOffsetStart: 5,
|
|
cursorOffsetEnd: 5,
|
|
});
|
|
});
|
|
|
|
it('formats underline text', () => {
|
|
expect(
|
|
secondarySyntaxFormatters['underline'].getFormatting(
|
|
exampleTextSelection,
|
|
),
|
|
).toEqual({
|
|
formattedText: '<u>selection</u>',
|
|
cursorOffsetStart: 3,
|
|
cursorOffsetEnd: 3,
|
|
});
|
|
});
|
|
|
|
it('formats strikethrough text', () => {
|
|
expect(
|
|
secondarySyntaxFormatters['strikethrough'].getFormatting(
|
|
exampleTextSelection,
|
|
),
|
|
).toEqual({
|
|
formattedText: '~~selection~~',
|
|
cursorOffsetStart: 2,
|
|
cursorOffsetEnd: 2,
|
|
});
|
|
});
|
|
|
|
it('adds a line divider when selection is empty', () => {
|
|
expect(secondarySyntaxFormatters['divider'].getFormatting('')).toEqual({
|
|
formattedText: '\n---\n',
|
|
cursorOffsetStart: 5,
|
|
cursorOffsetEnd: 5,
|
|
});
|
|
});
|
|
|
|
it('adds a line divider after given selection ', () => {
|
|
expect(
|
|
secondarySyntaxFormatters['divider'].getFormatting(exampleTextSelection),
|
|
).toEqual({
|
|
formattedText: 'selection\n---\n',
|
|
cursorOffsetStart: 14,
|
|
cursorOffsetEnd: 14,
|
|
});
|
|
});
|
|
});
|