2024-03-27 04:32:05 +00:00
|
|
|
|
import { StreamParser } from '@codemirror/language';
|
|
|
|
|
import { Tag } from '@lezer/highlight';
|
2023-12-06 18:49:40 +00:00
|
|
|
|
import CodeMirror from '../../src/codemirror.js';
|
2024-03-14 18:32:14 +00:00
|
|
|
|
import mediaWikiLang from '../../src/codemirror.mode.mediawiki.js';
|
2023-12-06 18:49:40 +00:00
|
|
|
|
import { mwModeConfig } from '../../src/codemirror.mode.mediawiki.config.js';
|
|
|
|
|
|
2024-03-11 21:03:28 +00:00
|
|
|
|
// NOTE: each test case should have a space before the closing </div>
|
|
|
|
|
// This is to avoid interactive UI components from showing up in the test output.
|
2023-12-06 18:49:40 +00:00
|
|
|
|
const testCases = [
|
|
|
|
|
{
|
|
|
|
|
title: 'p tags, extra closing tag',
|
|
|
|
|
input: 'this is <p><div>content</p></p>',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line">this is <span class="cm-mw-htmltag-bracket"><</span><span class="cm-mw-htmltag-name">p</span><span class="cm-mw-htmltag-bracket">></span><span class="cm-mw-htmltag-bracket"><</span><span class="cm-mw-htmltag-name">div</span><span class="cm-mw-htmltag-bracket">></span>content<span class="cm-mw-error"></p></span><span class="cm-mw-htmltag-bracket"></</span><span class="cm-mw-htmltag-name">p</span><span class="cm-mw-htmltag-bracket">></span> </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'HTML tag attributes',
|
|
|
|
|
input: '<span title="a<b"><b title="a>b"></b></span>',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-htmltag-bracket"><</span><span class="cm-mw-htmltag-name">span </span><span class="cm-mw-htmltag-attribute">title="a</span><span class="cm-mw-htmltag-attribute"><b"</span><span class="cm-mw-htmltag-bracket">></span><span class="cm-mw-htmltag-bracket"><</span><span class="cm-mw-htmltag-name">b </span><span class="cm-mw-htmltag-attribute">title="a</span><span class="cm-mw-htmltag-bracket">></span>b"><span class="cm-mw-htmltag-bracket"></</span><span class="cm-mw-htmltag-name">b</span><span class="cm-mw-htmltag-bracket">></span><span class="cm-mw-htmltag-bracket"></</span><span class="cm-mw-htmltag-name">span</span><span class="cm-mw-htmltag-bracket">></span> </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
2024-01-04 04:01:27 +00:00
|
|
|
|
{
|
|
|
|
|
title: 'ref tag attributes',
|
|
|
|
|
input: '<ref name="a<b"/>',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-exttag-bracket cm-mw-ext-ref"><</span><span class="cm-mw-exttag-name cm-mw-ext-ref">ref </span><span class="cm-mw-exttag-attribute cm-mw-ext-ref">name="a<b"</span><span class="cm-mw-exttag-bracket cm-mw-ext-ref">/></span> </div>'
|
2024-01-04 04:01:27 +00:00
|
|
|
|
},
|
2023-12-06 18:49:40 +00:00
|
|
|
|
{
|
|
|
|
|
title: 'indented table with caption and inline headings',
|
|
|
|
|
input: ' ::{| class="wikitable"\n |+ Caption\n |-\n ! Uno !! Dos\n |-\n | Foo || Bar\n |}',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-indenting"> ::</span><span class="cm-mw-table-bracket">{| </span><span class="cm-mw-table-definition">class</span><span class="cm-mw-table-definition">="wikitable"</span></div><div class="cm-line"><span class="cm-mw-table-delimiter"> |+ </span><span class="cm-mw-table-caption">Caption</span></div><div class="cm-line"><span class="cm-mw-table-delimiter"> |-</span></div><div class="cm-line"><span class="cm-mw-table-delimiter"> ! </span><span class="cm-mw-strong">Uno </span><span class="cm-mw-table-delimiter">!!</span><span class="cm-mw-strong"> Dos</span></div><div class="cm-line"><span class="cm-mw-table-delimiter"> |-</span></div><div class="cm-line"><span class="cm-mw-table-delimiter"> | </span>Foo <span class="cm-mw-table-delimiter">||</span> Bar</div><div class="cm-line"><span class="cm-mw-table-bracket"> |}</span> </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'apostrophe before italic',
|
|
|
|
|
input: 'plain l\'\'\'italic\'\'plain',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line">plain l\'<span class="cm-mw-apostrophes-italic">\'\'</span><span class="cm-mw-em">italic</span><span class="cm-mw-apostrophes-italic">\'\'</span>plain </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'free external links',
|
|
|
|
|
input: 'https://wikimedia.org [ftp://foo.bar FOO] //archive.org',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-free-extlink-protocol">https://</span><span class="cm-mw-free-extlink">wikimedia.</span><span class="cm-mw-free-extlink">org</span> <span class="cm-mw-link-ground cm-mw-extlink-bracket">[</span><span class="cm-mw-link-ground cm-mw-extlink-protocol">ftp://</span><span class="cm-mw-link-ground cm-mw-extlink">foo.bar</span><span class="cm-mw-link-ground"> </span><span class="cm-mw-link-ground cm-mw-extlink-text">FOO</span><span class="cm-mw-link-ground cm-mw-extlink-bracket">]</span> //archive.org </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
2024-01-18 18:06:06 +00:00
|
|
|
|
{
|
|
|
|
|
title: 'not free external links',
|
|
|
|
|
input: 'news: foo news:bar [news: baz]',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line">news: foo <span class="cm-mw-free-extlink-protocol">news:</span><span class="cm-mw-free-extlink">bar</span> [news: baz] </div>'
|
2024-01-18 18:06:06 +00:00
|
|
|
|
},
|
2023-12-06 18:49:40 +00:00
|
|
|
|
{
|
|
|
|
|
title: 'void tags',
|
|
|
|
|
input: 'a<br>b</br>c a<div>b<br>c</div>d',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line">a<span class="cm-mw-htmltag-bracket"><</span><span class="cm-mw-htmltag-name">br</span><span class="cm-mw-htmltag-bracket">></span>b<span class="cm-mw-error"></br></span>c a<span class="cm-mw-htmltag-bracket"><</span><span class="cm-mw-htmltag-name">div</span><span class="cm-mw-htmltag-bracket">></span>b<span class="cm-mw-htmltag-bracket"><</span><span class="cm-mw-htmltag-name">br</span><span class="cm-mw-htmltag-bracket">></span>c<span class="cm-mw-htmltag-bracket"></</span><span class="cm-mw-htmltag-name">div</span><span class="cm-mw-htmltag-bracket">></span>d </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'magic words',
|
|
|
|
|
input: '__NOTOC__',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-double-underscore">__NOTOC__</span> </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
2024-01-03 21:19:06 +00:00
|
|
|
|
{
|
|
|
|
|
title: 'nowiki',
|
|
|
|
|
input: '<nowiki>{{foo}}<p> </div> {{{</nowiki>\n<nowiki/><pre class="foo">\n\n {{bar}}</pre>',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-exttag-bracket cm-mw-ext-nowiki"><</span><span class="cm-mw-exttag-name cm-mw-ext-nowiki">nowiki</span><span class="cm-mw-exttag-bracket cm-mw-ext-nowiki">></span><span class="cm-mw-tag-nowiki">{{foo}}<p> </div> {{{</span><span class="cm-mw-exttag-bracket cm-mw-ext-nowiki"></</span><span class="cm-mw-exttag-name cm-mw-ext-nowiki">nowiki</span><span class="cm-mw-exttag-bracket cm-mw-ext-nowiki">></span></div><div class="cm-line"><span class="cm-mw-exttag-bracket cm-mw-ext-nowiki"><</span><span class="cm-mw-exttag-name cm-mw-ext-nowiki">nowiki</span><span class="cm-mw-exttag-bracket cm-mw-ext-nowiki">/></span><span class="cm-mw-exttag-bracket cm-mw-ext-pre"><</span><span class="cm-mw-exttag-name cm-mw-ext-pre">pre </span><span class="cm-mw-exttag-attribute cm-mw-ext-pre">class="foo"</span><span class="cm-mw-exttag-bracket cm-mw-ext-pre">></span></div><div class="cm-line"><br></div><div class="cm-line"><span class="cm-mw-tag-pre"> {{bar}}</span><span class="cm-mw-exttag-bracket cm-mw-ext-pre"></</span><span class="cm-mw-exttag-name cm-mw-ext-pre">pre</span><span class="cm-mw-exttag-bracket cm-mw-ext-pre">></span> </div>'
|
2024-01-04 04:01:27 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'ref tag with cite web, extraneous curly braces',
|
|
|
|
|
input: '<ref>{{cite web|2=foo}}}}</ref>',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-exttag-bracket cm-mw-ext-ref"><</span><span class="cm-mw-exttag-name cm-mw-ext-ref">ref</span><span class="cm-mw-exttag-bracket cm-mw-ext-ref">></span><span class="cm-mw-tag-ref cm-mw-template-ground cm-mw-template-bracket">{{</span><span class="cm-mw-tag-ref cm-mw-template-ground cm-mw-pagename cm-mw-template-name">cite</span><span class="cm-mw-tag-ref cm-mw-template-ground cm-mw-pagename cm-mw-template-name"> web</span><span class="cm-mw-tag-ref cm-mw-template-ground cm-mw-template-delimiter">|</span><span class="cm-mw-tag-ref cm-mw-template-ground cm-mw-template-argument-name">2=</span><span class="cm-mw-tag-ref cm-mw-template-ground cm-mw-template">foo</span><span class="cm-mw-tag-ref cm-mw-template-ground cm-mw-template-bracket">}}</span><span class="cm-mw-tag-ref">}</span><span class="cm-mw-tag-ref">}</span><span class="cm-mw-exttag-bracket cm-mw-ext-ref"></</span><span class="cm-mw-exttag-name cm-mw-ext-ref">ref</span><span class="cm-mw-exttag-bracket cm-mw-ext-ref">></span> </div>'
|
2024-01-03 21:19:06 +00:00
|
|
|
|
},
|
2023-12-06 18:49:40 +00:00
|
|
|
|
{
|
|
|
|
|
title: 'template with params and parser function',
|
|
|
|
|
input: '{{foo|1=bar|2={{{param|blah}}}|{{#if:{{{3|}}}|yes|no}}}}',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-template-ground cm-mw-template-bracket">{{</span><span class="cm-mw-template-ground cm-mw-pagename cm-mw-template-name">foo</span><span class="cm-mw-template-ground cm-mw-template-delimiter">|</span><span class="cm-mw-template-ground cm-mw-template-argument-name">1=</span><span class="cm-mw-template-ground cm-mw-template">bar</span><span class="cm-mw-template-ground cm-mw-template-delimiter">|</span><span class="cm-mw-template-ground cm-mw-template-argument-name">2=</span><span class="cm-mw-template-ground cm-mw-templatevariable-bracket">{{{</span><span class="cm-mw-template-ground cm-mw-templatevariable-name">param</span><span class="cm-mw-template-ground cm-mw-templatevariable-delimiter">|</span><span class="cm-mw-template-ground cm-mw-templatevariable">blah</span><span class="cm-mw-template-ground cm-mw-templatevariable-bracket">}}}</span><span class="cm-mw-template-ground cm-mw-template-delimiter">|</span><span class="cm-mw-template-ext-ground cm-mw-parserfunction-bracket">{{</span><span class="cm-mw-template-ext-ground cm-mw-parserfunction-name">#if</span><span class="cm-mw-template-ext-ground cm-mw-parserfunction-delimiter">:</span><span class="cm-mw-template-ext-ground cm-mw-templatevariable-bracket">{{{</span><span class="cm-mw-template-ext-ground cm-mw-templatevariable-name">3</span><span class="cm-mw-template-ext-ground cm-mw-templatevariable-delimiter">|</span><span class="cm-mw-template-ext-ground cm-mw-templatevariable-bracket">}}}</span><span class="cm-mw-template-ext-ground cm-mw-parserfunction-delimiter">|</span><span class="cm-mw-template-ext-ground cm-mw-parserfunction">yes</span><span class="cm-mw-template-ext-ground cm-mw-parserfunction-delimiter">|</span><span class="cm-mw-template-ext-ground cm-mw-parserfunction">no</span><span class="cm-mw-template-ext-ground cm-mw-parserfunction-bracket">}}</span><span class="cm-mw-template-ground cm-mw-template-bracket">}}</span> </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'T277767: newlines and comments in template names',
|
|
|
|
|
input: '{{#if: | {{some template\n<!-- comment --> }} }}',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-ext-ground cm-mw-parserfunction-bracket">{{</span><span class="cm-mw-ext-ground cm-mw-parserfunction-name">#if</span><span class="cm-mw-ext-ground cm-mw-parserfunction-delimiter">:</span><span class="cm-mw-ext-ground cm-mw-parserfunction"> </span><span class="cm-mw-ext-ground cm-mw-parserfunction-delimiter">|</span><span class="cm-mw-ext-ground cm-mw-parserfunction"> </span><span class="cm-mw-template-ext-ground cm-mw-template-bracket">{{</span><span class="cm-mw-template-ext-ground cm-mw-pagename cm-mw-template-name">some</span><span class="cm-mw-template-ext-ground cm-mw-pagename cm-mw-template-name"> template</span></div><div class="cm-line"><span class="cm-mw-template-ext-ground cm-mw-comment"><!-- comment --></span><span class="cm-mw-template-ext-ground cm-mw-template-bracket"> }}</span><span class="cm-mw-ext-ground cm-mw-parserfunction"> </span><span class="cm-mw-ext-ground cm-mw-parserfunction-bracket">}}</span> </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
2023-12-08 02:34:01 +00:00
|
|
|
|
{
|
|
|
|
|
title: 'T108450: template transclusion where the template name is a parameter',
|
|
|
|
|
input: '{{{{{1}}}|…}}',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-template-ground cm-mw-template-bracket">{{</span><span class="cm-mw-template-ground cm-mw-templatevariable-bracket">{{{</span><span class="cm-mw-template-ground cm-mw-templatevariable-name">1</span><span class="cm-mw-template-ground cm-mw-templatevariable-bracket">}}}</span><span class="cm-mw-template-ground cm-mw-template-delimiter">|</span><span class="cm-mw-template-ground cm-mw-template">…</span><span class="cm-mw-template-ground cm-mw-template-bracket">}}</span> </div>'
|
2023-12-08 02:34:01 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'T292967: table syntax where all | are escaped with the {{!}} parser function',
|
|
|
|
|
input: '{{{!}} class="wikitable"\n! header\n{{!}}-\n{{!}} cell\n{{!}}}',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line">{<span class="cm-mw-ext-ground cm-mw-parserfunction-bracket">{{</span><span class="cm-mw-ext-ground cm-mw-parserfunction-name">!</span><span class="cm-mw-ext-ground cm-mw-parserfunction-bracket">}}</span> class="wikitable"</div><div class="cm-line">! header</div><div class="cm-line"><span class="cm-mw-ext-ground cm-mw-parserfunction-bracket">{{</span><span class="cm-mw-ext-ground cm-mw-parserfunction-name">!</span><span class="cm-mw-ext-ground cm-mw-parserfunction-bracket">}}</span>-</div><div class="cm-line"><span class="cm-mw-ext-ground cm-mw-parserfunction-bracket">{{</span><span class="cm-mw-ext-ground cm-mw-parserfunction-name">!</span><span class="cm-mw-ext-ground cm-mw-parserfunction-bracket">}}</span> cell</div><div class="cm-line"><span class="cm-mw-ext-ground cm-mw-parserfunction-bracket">{{</span><span class="cm-mw-ext-ground cm-mw-parserfunction-name">!</span><span class="cm-mw-ext-ground cm-mw-parserfunction-bracket">}}</span>} </div>'
|
2023-12-08 02:34:01 +00:00
|
|
|
|
},
|
2024-01-18 19:16:00 +00:00
|
|
|
|
{
|
|
|
|
|
title: 'T324374: table cell attributes',
|
|
|
|
|
input: '{|\n|+ class="z" | Z\n! class="a" | A !! class="b" | B\n|-\n! class="c" | C || class="d" | D\n|-\n| class="e" | E || class="f" | F\n|}',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-table-bracket">{|</span></div><div class="cm-line"><span class="cm-mw-table-delimiter">|+ </span><span class="cm-mw-table-caption">class="z" </span><span class="cm-mw-table-delimiter">|</span><span class="cm-mw-table-caption"> Z</span></div><div class="cm-line"><span class="cm-mw-table-delimiter">! </span><span class="cm-mw-strong">class="a" </span><span class="cm-mw-table-delimiter">|</span><span class="cm-mw-strong"> A </span><span class="cm-mw-table-delimiter">!!</span><span class="cm-mw-strong"> class="b" </span><span class="cm-mw-table-delimiter">|</span><span class="cm-mw-strong"> B</span></div><div class="cm-line"><span class="cm-mw-table-delimiter">|-</span></div><div class="cm-line"><span class="cm-mw-table-delimiter">! </span><span class="cm-mw-strong">class="c" </span><span class="cm-mw-table-delimiter">|</span><span class="cm-mw-strong"> C </span><span class="cm-mw-table-delimiter">||</span><span class="cm-mw-strong"> class="d" </span><span class="cm-mw-table-delimiter">|</span><span class="cm-mw-strong"> D</span></div><div class="cm-line"><span class="cm-mw-table-delimiter">|-</span></div><div class="cm-line"><span class="cm-mw-table-delimiter">| </span>class="e" <span class="cm-mw-table-delimiter">|</span> E <span class="cm-mw-table-delimiter">||</span> class="f" <span class="cm-mw-table-delimiter">|</span> F</div><div class="cm-line"><span class="cm-mw-table-bracket">|}</span> </div>'
|
2024-01-18 19:16:00 +00:00
|
|
|
|
},
|
2023-12-06 18:49:40 +00:00
|
|
|
|
{
|
|
|
|
|
title: 'section headings',
|
|
|
|
|
input: '== My section ==\nFoo bar\n=== Blah ===\nBaz\n= { =\nText',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-section-header cm-mw-section-2">==</span><span class="cm-mw-section"> My section </span><span class="cm-mw-section-header">==</span></div><div class="cm-line">Foo bar</div><div class="cm-line"><span class="cm-mw-section-header cm-mw-section-3">===</span><span class="cm-mw-section"> Blah </span><span class="cm-mw-section-header">===</span></div><div class="cm-line">Baz</div><div class="cm-line"><span class="cm-mw-section-header cm-mw-section-1">=</span><span class="cm-mw-section"> </span><span class="cm-mw-section">{</span><span class="cm-mw-section"> </span><span class="cm-mw-section-header">=</span></div><div class="cm-line">Text </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'section headings with trailing comments',
|
|
|
|
|
input: '== My section == <!-- comment --> \nFoo bar\n=== Blah ===<!--comment-->\nBaz\n== <i>a</i> <!-- comment --> == <!--comment-->',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-section-header cm-mw-section-2">==</span><span class="cm-mw-section"> My section </span><span class="cm-mw-section-header">== </span><span class="cm-mw-comment"><!-- comment --></span> </div><div class="cm-line">Foo bar</div><div class="cm-line"><span class="cm-mw-section-header cm-mw-section-3">===</span><span class="cm-mw-section"> Blah </span><span class="cm-mw-section-header">===</span><span class="cm-mw-comment"><!--comment--></span></div><div class="cm-line">Baz</div><div class="cm-line"><span class="cm-mw-section-header cm-mw-section-2">==</span><span class="cm-mw-section"> </span><span class="cm-mw-htmltag-bracket"><</span><span class="cm-mw-htmltag-name">i</span><span class="cm-mw-htmltag-bracket">></span><span class="cm-mw-section">a</span><span class="cm-mw-htmltag-bracket"></</span><span class="cm-mw-htmltag-name">i</span><span class="cm-mw-htmltag-bracket">></span><span class="cm-mw-section"> </span><span class="cm-mw-comment"><!-- comment --></span><span class="cm-mw-section"> </span><span class="cm-mw-section-header">== </span><span class="cm-mw-comment"><!--comment--></span> </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'bullets and numbering, with invalid leading spacing',
|
|
|
|
|
input: '* bullet A\n* bullet B\n# one\n # two',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-list">*</span> bullet A</div><div class="cm-line"><span class="cm-mw-list">*</span> bullet B</div><div class="cm-line"><span class="cm-mw-list">#</span> one</div><div class="cm-line"><span class="cm-mw-skipformatting"> </span># two </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-01-18 15:39:31 +00:00
|
|
|
|
title: 'nested ordered, unordered and definition lists',
|
|
|
|
|
input: '*#;: item A\n#;:* item B\n;:*# item C\n:*#; item D',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-list">*#;:</span> item A</div><div class="cm-line"><span class="cm-mw-list">#;:*</span> item B</div><div class="cm-line"><span class="cm-mw-list">;:*#</span> item C</div><div class="cm-line"><span class="cm-mw-indenting">:*#;</span> item D </div>'
|
2024-01-18 15:39:31 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-12-06 18:49:40 +00:00
|
|
|
|
title: 'link with bold text',
|
|
|
|
|
input: '[[Link title|\'\'\'bold link\'\'\']]',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-link-ground cm-mw-link-bracket">[[</span><span class="cm-mw-link-ground cm-mw-link-pagename cm-mw-pagename">Link</span><span class="cm-mw-link-ground cm-mw-link-pagename cm-mw-pagename"> title</span><span class="cm-mw-link-ground cm-mw-link-delimiter">|</span><span class="cm-mw-link-ground cm-mw-link-text cm-mw-apostrophes">\'\'\'</span><span class="cm-mw-link-ground cm-mw-link-text cm-mw-strong">bold link</span><span class="cm-mw-link-ground cm-mw-link-text cm-mw-apostrophes">\'\'\'</span><span class="cm-mw-link-ground cm-mw-link-bracket">]]</span> </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'horizontal rule',
|
|
|
|
|
input: 'One\n----\nTwo',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line">One</div><div class="cm-line"><span class="cm-mw-hr">----</span></div><div class="cm-line">Two </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'comments',
|
|
|
|
|
input: '<!-- foo [[bar]] {{{param}}} -->',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-comment"><!-- foo [[bar]] {{{param}}} --></span> </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'signatures',
|
|
|
|
|
input: 'my sig ~~~ ~~~~ ~~~~~~~',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line">my sig <span class="cm-mw-signature">~~~</span> <span class="cm-mw-signature">~~~~</span> <span class="cm-mw-signature">~~~~~</span>~~ </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
},
|
2024-01-04 04:01:27 +00:00
|
|
|
|
{
|
|
|
|
|
title: 'capitalization of tags',
|
|
|
|
|
input: '<ref></Ref>',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-exttag-bracket cm-mw-ext-ref"><</span><span class="cm-mw-exttag-name cm-mw-ext-ref">ref</span><span class="cm-mw-exttag-bracket cm-mw-ext-ref">></span><span class="cm-mw-exttag-bracket cm-mw-ext-ref"></</span><span class="cm-mw-exttag-name cm-mw-ext-ref">Ref</span><span class="cm-mw-exttag-bracket cm-mw-ext-ref">></span> </div>'
|
2024-01-04 04:01:27 +00:00
|
|
|
|
},
|
2023-12-06 18:49:40 +00:00
|
|
|
|
{
|
|
|
|
|
title: 'multi-line tag',
|
|
|
|
|
input: '<div\nid="foo"\n>bar</div>',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-htmltag-bracket"><</span><span class="cm-mw-htmltag-name">div</span></div><div class="cm-line"><span class="cm-mw-htmltag-attribute">id="foo"</span></div><div class="cm-line"><span class="cm-mw-htmltag-bracket">></span>bar<span class="cm-mw-htmltag-bracket"></</span><span class="cm-mw-htmltag-name">div</span><span class="cm-mw-htmltag-bracket">></span> </div>'
|
2024-01-03 06:05:35 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'HTML entities',
|
|
|
|
|
input: '—\n[[/dev/null]]',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-html-entity">&#x2014;</span></div><div class="cm-line"><span class="cm-mw-link-ground cm-mw-link-bracket">[[</span><span class="cm-mw-link-ground cm-mw-html-entity">&#47;</span><span class="cm-mw-link-ground cm-mw-link-pagename cm-mw-pagename">dev/null</span><span class="cm-mw-link-ground cm-mw-link-bracket">]]</span> </div>'
|
2024-01-04 04:01:27 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'Extension tag with no TagMode',
|
|
|
|
|
input: '<myextension>foo\nbar\nbaz</myextension>',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-exttag-bracket cm-mw-ext-myextension"><</span><span class="cm-mw-exttag-name cm-mw-ext-myextension">myextension</span><span class="cm-mw-exttag-bracket cm-mw-ext-myextension">></span><span class="cm-mw-exttag">foo</span></div><div class="cm-line"><span class="cm-mw-exttag">bar</span></div><div class="cm-line"><span class="cm-mw-exttag">baz</span><span class="cm-mw-exttag-bracket cm-mw-ext-myextension"></</span><span class="cm-mw-exttag-name cm-mw-ext-myextension">myextension</span><span class="cm-mw-exttag-bracket cm-mw-ext-myextension">></span> </div>'
|
2024-01-19 00:33:58 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'Special characters',
|
|
|
|
|
input: 'Softhyphen\nzero-widthspace\nnon-breaking space\nnarrow nbsp',
|
|
|
|
|
// i18n messages are the keys because we don't stub mw.msg() in this test.
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line">Soft<img class="cm-widgetBuffer" aria-hidden="true"><span class="cm-specialChar" title="codemirror-control-character" aria-label="codemirror-control-character">•</span><img class="cm-widgetBuffer" aria-hidden="true">hyphen</div><div class="cm-line">zero-width<img class="cm-widgetBuffer" aria-hidden="true"><span class="cm-specialChar" title="codemirror-special-char-zero-width-space" aria-label="codemirror-special-char-zero-width-space">•</span><img class="cm-widgetBuffer" aria-hidden="true">space</div><div class="cm-line">non-breaking<img class="cm-widgetBuffer" aria-hidden="true"><span class="cm-special-char-nbsp" title="codemirror-special-char-nbsp" aria-label="codemirror-special-char-nbsp">·</span><img class="cm-widgetBuffer" aria-hidden="true">space</div><div class="cm-line">narrow<img class="cm-widgetBuffer" aria-hidden="true"><span class="cm-special-char-nbsp" title="codemirror-special-char-narrow-nbsp" aria-label="codemirror-special-char-narrow-nbsp">·</span><img class="cm-widgetBuffer" aria-hidden="true">nbsp </div>'
|
2024-02-28 02:03:46 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: 'Nested template calls',
|
|
|
|
|
input: '{{foo|{{bar|[[Test]]|{{baz|[[Test2]]}}}}}}',
|
2024-03-11 21:03:28 +00:00
|
|
|
|
output: '<div class="cm-line"><span class="cm-mw-template-ground cm-mw-template-bracket">{{</span><span class="cm-mw-template-ground cm-mw-pagename cm-mw-template-name">foo</span><span class="cm-mw-template-ground cm-mw-template-delimiter">|</span><span class="cm-mw-template2-ground cm-mw-template-bracket">{{</span><span class="cm-mw-template2-ground cm-mw-pagename cm-mw-template-name">bar</span><span class="cm-mw-template2-ground cm-mw-template-delimiter">|</span><span class="cm-mw-template2-link-ground cm-mw-link-bracket">[[</span><span class="cm-mw-template2-link-ground cm-mw-link-pagename cm-mw-pagename">Test</span><span class="cm-mw-template2-link-ground cm-mw-link-bracket">]]</span><span class="cm-mw-template2-ground cm-mw-template-delimiter">|</span><span class="cm-mw-template3-ground cm-mw-template-bracket">{{</span><span class="cm-mw-template3-ground cm-mw-pagename cm-mw-template-name">baz</span><span class="cm-mw-template3-ground cm-mw-template-delimiter">|</span><span class="cm-mw-template3-link-ground cm-mw-link-bracket">[[</span><span class="cm-mw-template3-link-ground cm-mw-link-pagename cm-mw-pagename">Test2</span><span class="cm-mw-template3-link-ground cm-mw-link-bracket">]]</span><span class="cm-mw-template3-ground cm-mw-template-bracket">}}</span><span class="cm-mw-template2-ground cm-mw-template-bracket">}}</span><span class="cm-mw-template-ground cm-mw-template-bracket">}}</span> </div>'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Setup CodeMirror instance.
|
|
|
|
|
const textarea = document.createElement( 'textarea' );
|
|
|
|
|
document.body.appendChild( textarea );
|
|
|
|
|
const cm = new CodeMirror( textarea );
|
2023-12-08 02:34:01 +00:00
|
|
|
|
// Stub the config normally provided by mw.config.get('extCodeMirrorConfig')
|
2024-03-14 18:32:14 +00:00
|
|
|
|
const mwLang = mediaWikiLang( {}, {
|
2024-01-18 18:06:06 +00:00
|
|
|
|
urlProtocols: 'ftp://|https://|news:',
|
2023-12-06 18:49:40 +00:00
|
|
|
|
doubleUnderscore: [ {
|
|
|
|
|
__notoc__: 'notoc'
|
2023-12-08 02:34:01 +00:00
|
|
|
|
} ],
|
|
|
|
|
functionSynonyms: [ {}, {
|
|
|
|
|
'!': '!'
|
2024-01-03 21:19:06 +00:00
|
|
|
|
} ],
|
|
|
|
|
tags: {
|
|
|
|
|
nowiki: true,
|
2024-01-04 04:01:27 +00:00
|
|
|
|
pre: true,
|
|
|
|
|
ref: true,
|
|
|
|
|
references: true,
|
|
|
|
|
// Made-up tag, for testing when a corresponding TagMode is not configured.
|
|
|
|
|
myextension: true
|
|
|
|
|
},
|
|
|
|
|
tagModes: {
|
|
|
|
|
ref: 'mediawiki',
|
|
|
|
|
references: 'mediawiki'
|
2024-01-03 21:19:06 +00:00
|
|
|
|
}
|
2023-12-06 18:49:40 +00:00
|
|
|
|
} );
|
|
|
|
|
cm.initialize( [ ...cm.defaultExtensions, mwLang ] );
|
|
|
|
|
|
|
|
|
|
describe( 'CodeMirrorModeMediaWiki', () => {
|
|
|
|
|
it.each( testCases )(
|
|
|
|
|
'syntax highlighting ($title)',
|
|
|
|
|
( { input, output } ) => {
|
|
|
|
|
cm.view.dispatch( {
|
|
|
|
|
changes: {
|
|
|
|
|
from: 0,
|
|
|
|
|
to: cm.view.state.doc.length,
|
2024-03-11 21:03:28 +00:00
|
|
|
|
insert: input + ' '
|
|
|
|
|
},
|
|
|
|
|
// Above we add an extra space to the end, and here we've move the cursor there.
|
|
|
|
|
// This is to avoid bracket matching and other interactive UI components
|
|
|
|
|
// from showing up in the test output.
|
|
|
|
|
selection: { anchor: input.length + 1 }
|
2023-12-06 18:49:40 +00:00
|
|
|
|
} );
|
|
|
|
|
cm.$textarea.textSelection = jest.fn().mockReturnValue( input );
|
|
|
|
|
expect( cm.view.dom.querySelector( '.cm-content' ).innerHTML ).toStrictEqual( output );
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
it( 'configuration contains all expected tokens', () => {
|
|
|
|
|
expect( Object.keys( mwModeConfig.tags ) ).toStrictEqual( [
|
|
|
|
|
'apostrophes',
|
|
|
|
|
'apostrophesBold',
|
|
|
|
|
'apostrophesItalic',
|
|
|
|
|
'comment',
|
|
|
|
|
'doubleUnderscore',
|
|
|
|
|
'extLink',
|
|
|
|
|
'extLinkBracket',
|
|
|
|
|
'extLinkProtocol',
|
|
|
|
|
'extLinkText',
|
|
|
|
|
'hr',
|
|
|
|
|
'htmlTagAttribute',
|
|
|
|
|
'htmlTagBracket',
|
|
|
|
|
'htmlTagName',
|
|
|
|
|
'indenting',
|
|
|
|
|
'linkBracket',
|
|
|
|
|
'linkDelimiter',
|
|
|
|
|
'linkText',
|
|
|
|
|
'linkToSection',
|
|
|
|
|
'list',
|
|
|
|
|
'parserFunction',
|
|
|
|
|
'parserFunctionBracket',
|
|
|
|
|
'parserFunctionDelimiter',
|
|
|
|
|
'parserFunctionName',
|
|
|
|
|
'sectionHeader',
|
|
|
|
|
'sectionHeader1',
|
|
|
|
|
'sectionHeader2',
|
|
|
|
|
'sectionHeader3',
|
|
|
|
|
'sectionHeader4',
|
|
|
|
|
'sectionHeader5',
|
|
|
|
|
'sectionHeader6',
|
|
|
|
|
'signature',
|
|
|
|
|
'tableBracket',
|
|
|
|
|
'tableDefinition',
|
|
|
|
|
'tableDelimiter',
|
|
|
|
|
'template',
|
|
|
|
|
'templateArgumentName',
|
|
|
|
|
'templateBracket',
|
|
|
|
|
'templateDelimiter',
|
|
|
|
|
'templateName',
|
|
|
|
|
'templateVariable',
|
|
|
|
|
'templateVariableBracket',
|
|
|
|
|
'templateVariableName',
|
|
|
|
|
// Custom tags
|
|
|
|
|
'em',
|
|
|
|
|
'error',
|
2024-01-03 21:19:06 +00:00
|
|
|
|
'extNowiki',
|
|
|
|
|
'extPre',
|
|
|
|
|
'extTag',
|
|
|
|
|
'extTagAttribute',
|
|
|
|
|
'extTagBracket',
|
|
|
|
|
'extTagName',
|
2023-12-06 18:49:40 +00:00
|
|
|
|
'freeExtLink',
|
|
|
|
|
'freeExtLinkProtocol',
|
2024-01-03 06:05:35 +00:00
|
|
|
|
'htmlEntity',
|
2023-12-06 18:49:40 +00:00
|
|
|
|
'link',
|
|
|
|
|
'linkPageName',
|
2024-01-03 21:19:06 +00:00
|
|
|
|
'nowiki',
|
2023-12-06 18:49:40 +00:00
|
|
|
|
'pageName',
|
2024-01-03 21:19:06 +00:00
|
|
|
|
'pre',
|
2024-01-07 07:27:59 +00:00
|
|
|
|
'section',
|
2023-12-06 18:49:40 +00:00
|
|
|
|
'skipFormatting',
|
|
|
|
|
'strong',
|
|
|
|
|
'tableCaption',
|
2024-02-28 02:03:46 +00:00
|
|
|
|
'templateVariableDelimiter'
|
2023-12-06 18:49:40 +00:00
|
|
|
|
] );
|
|
|
|
|
} );
|
2024-03-27 04:32:05 +00:00
|
|
|
|
|
|
|
|
|
it( 'configuration has a TagStyle for all expected CSS classes', () => {
|
|
|
|
|
/** @type {StreamParser} */
|
|
|
|
|
const mockContext = {
|
|
|
|
|
tokenTable: jest.fn().mockReturnValue( Tag.define() )
|
|
|
|
|
};
|
|
|
|
|
const cssClasses = mwModeConfig.getTagStyles( mockContext )
|
|
|
|
|
.map( ( tagStyle ) => tagStyle.class );
|
|
|
|
|
expect( cssClasses ).toStrictEqual( [
|
|
|
|
|
'cm-mw-apostrophes',
|
|
|
|
|
'cm-mw-apostrophes-bold',
|
|
|
|
|
'cm-mw-apostrophes-italic',
|
|
|
|
|
'cm-mw-comment',
|
|
|
|
|
'cm-mw-double-underscore',
|
|
|
|
|
'cm-mw-extlink',
|
|
|
|
|
'cm-mw-extlink-bracket',
|
|
|
|
|
'cm-mw-extlink-protocol',
|
|
|
|
|
'cm-mw-extlink-text',
|
|
|
|
|
'cm-mw-hr',
|
|
|
|
|
'cm-mw-htmltag-attribute',
|
|
|
|
|
'cm-mw-htmltag-bracket',
|
|
|
|
|
'cm-mw-htmltag-name',
|
|
|
|
|
'cm-mw-indenting',
|
|
|
|
|
'cm-mw-link-bracket',
|
|
|
|
|
'cm-mw-link-delimiter',
|
|
|
|
|
'cm-mw-link-text',
|
|
|
|
|
'cm-mw-link-tosection',
|
|
|
|
|
'cm-mw-list',
|
|
|
|
|
'cm-mw-parserfunction',
|
|
|
|
|
'cm-mw-parserfunction-bracket',
|
|
|
|
|
'cm-mw-parserfunction-delimiter',
|
|
|
|
|
'cm-mw-parserfunction-name',
|
|
|
|
|
'cm-mw-section-header',
|
|
|
|
|
'cm-mw-section-1',
|
|
|
|
|
'cm-mw-section-2',
|
|
|
|
|
'cm-mw-section-3',
|
|
|
|
|
'cm-mw-section-4',
|
|
|
|
|
'cm-mw-section-5',
|
|
|
|
|
'cm-mw-section-6',
|
|
|
|
|
'cm-mw-signature',
|
|
|
|
|
'cm-mw-table-bracket',
|
|
|
|
|
'cm-mw-table-definition',
|
|
|
|
|
'cm-mw-table-delimiter',
|
|
|
|
|
'cm-mw-template',
|
|
|
|
|
'cm-mw-template-argument-name',
|
|
|
|
|
'cm-mw-template-bracket',
|
|
|
|
|
'cm-mw-template-delimiter',
|
|
|
|
|
'cm-mw-pagename cm-mw-template-name',
|
|
|
|
|
'cm-mw-templatevariable',
|
|
|
|
|
'cm-mw-templatevariable-bracket',
|
|
|
|
|
'cm-mw-templatevariable-name',
|
|
|
|
|
// Custom tags
|
|
|
|
|
'cm-mw-em',
|
|
|
|
|
'cm-mw-error',
|
|
|
|
|
'cm-mw-ext-nowiki',
|
|
|
|
|
'cm-mw-ext-pre',
|
|
|
|
|
'cm-mw-exttag-bracket',
|
|
|
|
|
'cm-mw-exttag',
|
|
|
|
|
'cm-mw-exttag-attribute',
|
|
|
|
|
'cm-mw-exttag-name',
|
|
|
|
|
'cm-mw-free-extlink',
|
|
|
|
|
'cm-mw-free-extlink-protocol',
|
|
|
|
|
'cm-mw-html-entity',
|
|
|
|
|
'cm-mw-link',
|
|
|
|
|
'cm-mw-link-pagename',
|
|
|
|
|
'cm-mw-tag-nowiki',
|
|
|
|
|
'cm-mw-pagename',
|
|
|
|
|
'cm-mw-tag-pre',
|
|
|
|
|
'cm-mw-section',
|
|
|
|
|
'cm-mw-skipformatting',
|
|
|
|
|
'cm-mw-strong',
|
|
|
|
|
'cm-mw-table-caption',
|
|
|
|
|
'cm-mw-templatevariable-delimiter',
|
|
|
|
|
// Dynamically generated tags
|
|
|
|
|
'cm-mw-ext-ground',
|
|
|
|
|
'cm-mw-ext-link-ground',
|
|
|
|
|
'cm-mw-ext2-ground',
|
|
|
|
|
'cm-mw-ext2-link-ground',
|
|
|
|
|
'cm-mw-ext3-ground',
|
|
|
|
|
'cm-mw-ext3-link-ground',
|
|
|
|
|
'cm-mw-link-ground',
|
|
|
|
|
'cm-mw-template-ext-ground',
|
|
|
|
|
'cm-mw-template-ext-link-ground',
|
|
|
|
|
'cm-mw-template-ext2-ground',
|
|
|
|
|
'cm-mw-template-ext2-link-ground',
|
|
|
|
|
'cm-mw-template-ext3-ground',
|
|
|
|
|
'cm-mw-template-ext3-link-ground',
|
|
|
|
|
'cm-mw-template-ground',
|
|
|
|
|
'cm-mw-template-link-ground',
|
|
|
|
|
'cm-mw-template2-ext-ground',
|
|
|
|
|
'cm-mw-template2-ext-link-ground',
|
|
|
|
|
'cm-mw-template2-ext2-ground',
|
|
|
|
|
'cm-mw-template2-ext2-link-ground',
|
|
|
|
|
'cm-mw-template2-ext3-ground',
|
|
|
|
|
'cm-mw-template2-ext3-link-ground',
|
|
|
|
|
'cm-mw-template2-ground',
|
|
|
|
|
'cm-mw-template2-link-ground',
|
|
|
|
|
'cm-mw-template3-ext-ground',
|
|
|
|
|
'cm-mw-template3-ext-link-ground',
|
|
|
|
|
'cm-mw-template3-ext2-ground',
|
|
|
|
|
'cm-mw-template3-ext2-link-ground',
|
|
|
|
|
'cm-mw-template3-ext3-ground',
|
|
|
|
|
'cm-mw-template3-ext3-link-ground',
|
|
|
|
|
'cm-mw-template3-ground',
|
|
|
|
|
'cm-mw-template3-link-ground',
|
|
|
|
|
/** Added by the MW config stub above {@link mwLang} */
|
|
|
|
|
'cm-mw-tag-ref',
|
|
|
|
|
'cm-mw-ext-ref',
|
|
|
|
|
'cm-mw-tag-references',
|
|
|
|
|
'cm-mw-ext-references',
|
|
|
|
|
'cm-mw-tag-myextension',
|
|
|
|
|
'cm-mw-ext-myextension'
|
|
|
|
|
] );
|
|
|
|
|
} );
|
2023-12-06 18:49:40 +00:00
|
|
|
|
} );
|