Shawn Erquhart 18c579d0e9 feat: Code Widget + Markdown Widget Internal Overhaul (#2828)
* wip - upgrade to slate 0.43

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* finish list handling logic

* add plugins directory

* tests wip

* setup testing

* wip

* add selection commands

* finish list testing

* stuff

* add codemirror

* abstract codemirror from slate

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* codemirror mostly working, some bugs

* upgrade to slate 46

* upgrade to slate 47

* wip

* wip

* progress

* wip

* mostly working links with surrounding marks

* wip

* tests passing

* add test

* fix formatting

* update snapshots

* close self closing tag in markdown html output

* wip - commonmark

* hold on commonmark work

* all tests passing

* fix e2e specs

* ignore tests in esm builds

* break/backspace plugins wip

* finish enter/backspace spec

* fix soft break handling

* wip - editor component deletion

* add insertion points

* make insertion points invisible

* fix empty mark nodes output to markdown

* fix pasting

* improve insertion points

* add static bottom insertion point

* improve click handling at insertion points

* restore current table functionality

* add paste support for Slate fragments

* support cut/copy markdown, paste between rich/raw editor

* fix copy paste

* wip - paste/select bug fixing

* fixed known slate issues

* split plugins

* fix editor toggles

* force text cursor in code widget

* wip - reorg plugins

* finish markdown control reorg

* configure plugin types

* quote block adjacent handling with tests

* wip

* finish quote logic and tests

* fix copy paste plugin migration regressions

* fix force insert before node

* fix trailing insertion point

* remove empty headers

* codemirror working properly in markdown widget

* return focus to codemirror on lang select enter

* fix state issues for widgets with local state

* wip - vim working, just need to work out distribution

* add settings pane

* wip - default modes

* fix deps

* add programming language data

* implement linguist langs in code widget

* everything built in

* remove old registration code, fix focus styling

* fix/update linting setup

* fix js lint errors

* remove stylelint from format script

* fix remaining linting errors

* fix reducer test failures

* chore: update commitlint for worktree support

* chore: fix remaining tests

* chore: drop unused monaco plugin

* chore: remove extraneous global styles rendering

* chore: fix failing tests

* fix: tests

* fix: quote/list nesting (tests still broken)

* fix: update quote tests

* chore: bring back code widget test config

* fix: autofocus

* fix: code blocks without the code widget

* fix: code editor component state issues

* fix: error

* fix: add code block test, few fixes

* chore: remove notes

* fix: [wip] update stateful shortcodes on undo/redo

* fix: support code styled links, handle unknown langs

* fix: few fixes

* fix: autofocus on insert, focus on all clicks

* fix: linting

* fix: autofocus

* fix: update code block fixture

* fix: remove unused cypress snapshot plugin

* fix: drop node 8 test, add node 12

* fix: use lodash.flatten instead of Array.flat

* fix: remove console logs
2019-12-16 19:17:37 +02:00

125 lines
3.6 KiB
JavaScript

import { flow } from 'lodash';
import { tests as commonmarkSpec } from 'commonmark-spec';
import commonmark from 'commonmark';
import { markdownToSlate, slateToMarkdown } from '../index.js';
const skips = [
{
number: [456],
reason: 'Remark ¯\\_(ツ)_/¯',
},
{
number: [416, 417, 424, 425, 426, 431, 457, 460, 462, 464, 467],
reason: 'Remark does not support infinite (redundant) nested marks',
},
{
number: [455, 469, 470, 471],
reason: 'Remark parses the initial set of identical nested delimiters first',
},
{
number: [473, 476, 478, 480],
reason: 'we convert underscores to asterisks for strong/emphasis',
},
{ number: 490, reason: 'Remark strips pointy enclosing pointy brackets from link url' },
{ number: 503, reason: 'Remark allows non-breaking space between link url and title' },
{ number: 507, reason: 'Remark allows a space between link alt and url' },
{
number: [
511,
516,
525,
528,
529,
530,
532,
533,
534,
540,
541,
542,
543,
546,
548,
560,
565,
567,
],
reason: 'we convert link references to standard links, but Remark also fails these',
},
{
number: [569, 570, 571, 572, 573, 581, 585],
reason: 'Remark does not recognize or remove marks in image alt text',
},
{ number: 589, reason: 'Remark does not honor backslash escape of image exclamation point' },
{ number: 593, reason: 'Remark removes "mailto:" from autolink text' },
{ number: 599, reason: 'Remark does not escape all expected entities' },
{ number: 602, reason: 'Remark allows autolink emails to contain backslashes' },
];
const onlys = [
// just add the spec number, eg:
// 431,
];
/**
* Each test receives input markdown and output html as expected for Commonmark
* compliance. To test all of our handling in one go, we serialize the markdown
* into our Slate AST, then back to raw markdown, and finally to HTML.
*/
const reader = new commonmark.Parser();
const writer = new commonmark.HtmlRenderer();
const parseWithCommonmark = markdown => {
const parsed = reader.parse(markdown);
return writer.render(parsed);
};
const parse = flow([markdownToSlate, slateToMarkdown]);
/**
* Passing this test suite requires 100% Commonmark compliance. There are 624
* tests, of which we're passing about 300 as of introduction of this suite. To
* work on improving Commonmark support, update __fixtures__/commonmarkExpected.json
*/
describe.skip('Commonmark support', function() {
const specs =
onlys.length > 0
? commonmarkSpec.filter(({ number }) => onlys.includes(number))
: commonmarkSpec;
specs.forEach(spec => {
const skip = skips.find(({ number }) => {
return Array.isArray(number) ? number.includes(spec.number) : number === spec.number;
});
const specUrl = `https://spec.commonmark.org/0.29/#example-${spec.number}`;
const parsed = parse(spec.markdown);
const commonmarkParsedHtml = parseWithCommonmark(parsed);
const description = `
${spec.section}
${specUrl}
Spec:
${JSON.stringify(spec, null, 2)}
Markdown input:
${spec.markdown}
Markdown parsed through Slate/Remark and back to Markdown:
${parsed}
HTML output:
${commonmarkParsedHtml}
Expected HTML output:
${spec.html}
`;
if (skip) {
const showMessage = Array.isArray(skip.number) ? skip.number[0] === spec.number : true;
if (showMessage) {
//console.log(`skipping spec ${skip.number}\n${skip.reason}\n${specUrl}`);
}
}
const testFn = skip ? test.skip : test;
testFn(description, () => {
expect(commonmarkParsedHtml).toEqual(spec.html);
});
});
});