import CodeMirror from '../../src/codemirror.js'; import { mediaWikiLang } from '../../src/codemirror.mode.mediawiki.js'; import { mwModeConfig } from '../../src/codemirror.mode.mediawiki.config.js'; /* eslint-disable max-len */ const testCases = [ { title: 'p tags, extra closing tag', input: 'this is

content

', output: '
this is <p><div>content</p></p>
' }, { title: 'HTML tag attributes', input: '', output: '
<span title="a<b"><b title="a>b"></b></span>
' }, // FIXME: implement tagModes system so other extensions can register tags in CodeMirror // { // title: 'ref tag attributes', // input: '', // output: extCiteLoaded ? // '
<ref name="a<b"/>
' : // '
<ref name="a<b"/>
' // }, { title: 'indented table with caption and inline headings', input: ' ::{| class="wikitable"\n |+ Caption\n |-\n ! Uno !! Dos\n |-\n | Foo || Bar\n |}', output: '
::{| class="wikitable"
|+ Caption
|-
! Uno !! Dos
|-
| Foo || Bar
|}
' }, { title: 'apostrophe before italic', input: 'plain l\'\'\'italic\'\'plain', output: '
plain l\'\'\'italic\'\'plain
' }, { title: 'free external links', input: 'https://wikimedia.org [ftp://foo.bar FOO] //archive.org', output: '
https://wikimedia.org [ftp://foo.bar FOO] //archive.org
' }, { title: 'void tags', input: 'a
b
c a
b
c
d', output: '
a<br>b</br>c a<div>b<br>c</div>d
' }, { title: 'magic words', input: '__NOTOC__', output: '
__NOTOC__
' }, { title: 'nowiki', input: '{{foo}}

{{{\n
\n\n {{bar}}
', output: '
<nowiki>{{foo}}<p> </div> {{{</nowiki>
<nowiki/><pre class="foo">

{{bar}}</pre>
' }, // { // title: 'ref tag with cite web, extraneous curly braces', // input: '{{cite web|2=foo}}}}', // output: extCiteLoaded ? // '
<ref>{{cite web|2=foo}}}}</ref>' : // '
<ref>{{cite web|2=foo}}}}</ref>' // }, { title: 'template with params and parser function', input: '{{foo|1=bar|2={{{param|blah}}}|{{#if:{{{3|}}}|yes|no}}}}', output: '
{{foo|1=bar|2={{{param|blah}}}|{{#if:{{{3|}}}|yes|no}}}}
' }, { title: 'T277767: newlines and comments in template names', input: '{{#if: | {{some template\n }} }}', output: '
{{#if: | {{some template
<!-- comment --> }} }}
' }, { title: 'T108450: template transclusion where the template name is a parameter', input: '{{{{{1}}}|…}}', output: '
{{{{{1}}}|}}
' }, { title: 'T292967: table syntax where all | are escaped with the {{!}} parser function', input: '{{{!}} class="wikitable"\n! header\n{{!}}-\n{{!}} cell\n{{!}}}', output: '
{{{!}} class="wikitable"
! header
{{!}}-
{{!}} cell
{{!}}}
' }, { title: 'section headings', input: '== My section ==\nFoo bar\n=== Blah ===\nBaz\n= { =\nText', output: '
== My section ==
Foo bar
=== Blah ===
Baz
= { =
Text
' }, { title: 'section headings with trailing comments', input: '== My section == \nFoo bar\n=== Blah ===\nBaz\n== a == ', output: '
== My section == <!-- comment -->
Foo bar
=== Blah ===<!--comment-->
Baz
== <i>a</i> <!-- comment --> == <!--comment-->
' }, { title: 'bullets and numbering, with invalid leading spacing', input: '* bullet A\n* bullet B\n# one\n # two', output: '
* bullet A
* bullet B
# one
# two
' }, { title: 'link with bold text', input: '[[Link title|\'\'\'bold link\'\'\']]', output: '
[[Link title|\'\'\'bold link\'\'\']]
' }, { title: 'horizontal rule', input: 'One\n----\nTwo', output: '
One
----
Two
' }, { title: 'comments', input: '', output: '
<!-- foo [[bar]] {{{param}}} -->
' }, { title: 'signatures', input: 'my sig ~~~ ~~~~ ~~~~~~~', output: '
my sig ~~~ ~~~~ ~~~~~~~
' }, // { // title: 'new', // input: '', // output: extCiteLoaded ? // '
<ref></Ref>
' : // '
<ref></Ref>
' // }, { title: 'multi-line tag', input: 'bar
', output: '
<div
id="foo"
>bar</div>
' }, { title: 'HTML entities', input: '—\n[[/dev/null]]', output: '
&#x2014;
[[&#47;dev/null]]
' } ]; // Setup CodeMirror instance. const textarea = document.createElement( 'textarea' ); document.body.appendChild( textarea ); const cm = new CodeMirror( textarea ); // Stub the config normally provided by mw.config.get('extCodeMirrorConfig') const mwLang = mediaWikiLang( { urlProtocols: 'ftp://|https://', doubleUnderscore: [ { __notoc__: 'notoc' } ], functionSynonyms: [ {}, { '!': '!' } ], tags: { nowiki: true, pre: true } } ); 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, insert: input } } ); 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', 'extGround', 'extNowiki', 'extPre', 'extTag', 'extTagAttribute', 'extTagBracket', 'extTagName', 'freeExtLink', 'freeExtLinkProtocol', 'htmlEntity', 'link', 'linkGround', 'linkPageName', 'nowiki', 'pageName', 'pre', 'section', 'skipFormatting', 'strong', 'tableCaption', 'templateGround', 'templateExtGround', 'templateLinkGround', 'templateVariableDelimiter', 'template2ExtGround', 'template2Ground', 'template3ExtGround', 'template3Ground' ] ); } ); } );