Merge "CodeMirrorModeMediaWikiConfig: add missing tokens for nested templates"

This commit is contained in:
jenkins-bot 2024-03-07 04:23:56 +00:00 committed by Gerrit Code Review
commit 4c01432da8
5 changed files with 76 additions and 118 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -16,27 +16,39 @@ class CodeMirrorModeMediaWikiConfig {
} }
/** /**
* Register a tag in CodeMirror. The generated CSS class will be of the form 'cm-mw-ext-tagname' * Register a token for the given tag in CodeMirror. The generated CSS class will be of
* This is for internal use to dynamically register tags from other MediaWiki extensions. * the form 'cm-mw-ext-tagname'. This is for internal use to dynamically register tags
* from other MediaWiki extensions.
* *
* @see https://www.mediawiki.org/wiki/Extension:CodeMirror#Extension_integration * @see https://www.mediawiki.org/wiki/Extension:CodeMirror#Extension_integration
* @param {string} tag * @param {string} tag
* @param {Tag} parent * @param {Tag} [parent]
* @internal * @internal
*/ */
addTag( tag, parent ) { addTag( tag, parent = null ) {
if ( this.tokenTable[ `mw-tag-${ tag }` ] ) { if ( this.tokenTable[ `mw-tag-${ tag }` ] ) {
return; return;
} }
this.tokenTable[ `mw-tag-${ tag }` ] = Tag.define( parent ); this.addToken( `mw-tag-${ tag }`, parent );
this.tokenTable[ `mw-ext-${ tag }` ] = Tag.define( parent ); this.addToken( `mw-ext-${ tag }`, parent );
}
/**
* Dynamically register a token in CodeMirror.
* This is solely for use by this.addTag() and CodeMirrorModeMediaWiki.makeLocalStyle().
*
* @param {string} token
* @param {Tag} [parent]
* @internal
*/
addToken( token, parent = null ) {
if ( this.tokenTable[ token ] ) {
return;
}
this.tokenTable[ token ] = Tag.define( parent );
this.extHighlightStyles.push( { this.extHighlightStyles.push( {
tag: this.tokenTable[ `mw-tag-${ tag }` ], tag: this.tokenTable[ token ],
class: `cm-mw-tag-${ tag }` class: `cm-${ token }`
} );
this.extHighlightStyles.push( {
tag: this.tokenTable[ `mw-ext-${ tag }` ],
class: `cm-mw-ext-${ tag }`
} ); } );
} }
@ -152,7 +164,6 @@ class CodeMirrorModeMediaWikiConfig {
return { return {
em: 'mw-em', em: 'mw-em',
error: 'mw-error', error: 'mw-error',
extGround: 'mw-ext-ground',
extNowiki: 'mw-ext-nowiki', extNowiki: 'mw-ext-nowiki',
extPre: 'mw-ext-pre', extPre: 'mw-ext-pre',
extTag: 'mw-exttag', extTag: 'mw-exttag',
@ -163,7 +174,6 @@ class CodeMirrorModeMediaWikiConfig {
freeExtLinkProtocol: 'mw-free-extlink-protocol', freeExtLinkProtocol: 'mw-free-extlink-protocol',
htmlEntity: 'mw-html-entity', htmlEntity: 'mw-html-entity',
link: 'mw-link', link: 'mw-link',
linkGround: 'mw-link-ground',
linkPageName: 'mw-link-pagename', linkPageName: 'mw-link-pagename',
nowiki: 'mw-tag-nowiki', nowiki: 'mw-tag-nowiki',
pageName: 'mw-pagename', pageName: 'mw-pagename',
@ -172,14 +182,7 @@ class CodeMirrorModeMediaWikiConfig {
skipFormatting: 'mw-skipformatting', skipFormatting: 'mw-skipformatting',
strong: 'mw-strong', strong: 'mw-strong',
tableCaption: 'mw-table-caption', tableCaption: 'mw-table-caption',
templateGround: 'mw-template-ground', templateVariableDelimiter: 'mw-templatevariable-delimiter'
templateExtGround: 'mw-template-ext-ground',
templateLinkGround: 'mw-template-link-ground',
templateVariableDelimiter: 'mw-templatevariable-delimiter',
template2ExtGround: 'mw-template2-ext-ground',
template2Ground: 'mw-template2-ground',
template3ExtGround: 'mw-template3-ext-ground',
template3Ground: 'mw-template3-ground'
}; };
} }
@ -197,7 +200,6 @@ class CodeMirrorModeMediaWikiConfig {
return { return {
[ this.tags.em ]: Tag.define(), [ this.tags.em ]: Tag.define(),
[ this.tags.error ]: Tag.define(), [ this.tags.error ]: Tag.define(),
[ this.tags.extGround ]: Tag.define(),
[ this.tags.extNowiki ]: Tag.define(), [ this.tags.extNowiki ]: Tag.define(),
[ this.tags.extPre ]: Tag.define(), [ this.tags.extPre ]: Tag.define(),
[ this.tags.extTag ]: Tag.define(), [ this.tags.extTag ]: Tag.define(),
@ -208,7 +210,6 @@ class CodeMirrorModeMediaWikiConfig {
[ this.tags.freeExtLinkProtocol ]: Tag.define(), [ this.tags.freeExtLinkProtocol ]: Tag.define(),
[ this.tags.htmlEntity ]: Tag.define(), [ this.tags.htmlEntity ]: Tag.define(),
[ this.tags.link ]: Tag.define(), [ this.tags.link ]: Tag.define(),
[ this.tags.linkGround ]: Tag.define(),
[ this.tags.linkPageName ]: Tag.define(), [ this.tags.linkPageName ]: Tag.define(),
[ this.tags.nowiki ]: Tag.define(), [ this.tags.nowiki ]: Tag.define(),
[ this.tags.pageName ]: Tag.define(), [ this.tags.pageName ]: Tag.define(),
@ -217,14 +218,7 @@ class CodeMirrorModeMediaWikiConfig {
[ this.tags.skipFormatting ]: Tag.define(), [ this.tags.skipFormatting ]: Tag.define(),
[ this.tags.strong ]: Tag.define(), [ this.tags.strong ]: Tag.define(),
[ this.tags.tableCaption ]: Tag.define(), [ this.tags.tableCaption ]: Tag.define(),
[ this.tags.templateGround ]: Tag.define(), [ this.tags.templateVariableDelimiter ]: Tag.define()
[ this.tags.templateExtGround ]: Tag.define(),
[ this.tags.templateLinkGround ]: Tag.define(),
[ this.tags.templateVariableDelimiter ]: Tag.define(),
[ this.tags.template2ExtGround ]: Tag.define(),
[ this.tags.template2Ground ]: Tag.define(),
[ this.tags.template3ExtGround ]: Tag.define(),
[ this.tags.template3Ground ]: Tag.define()
}; };
} }
@ -419,10 +413,6 @@ class CodeMirrorModeMediaWikiConfig {
tag: context.tokenTable[ this.tags.error ], tag: context.tokenTable[ this.tags.error ],
class: 'cm-mw-error' class: 'cm-mw-error'
}, },
{
tag: context.tokenTable[ this.tags.extGround ],
class: 'cm-mw-ext-ground'
},
{ {
tag: context.tokenTable[ this.tags.extNowiki ], tag: context.tokenTable[ this.tags.extNowiki ],
class: 'cm-mw-ext-nowiki' class: 'cm-mw-ext-nowiki'
@ -459,10 +449,6 @@ class CodeMirrorModeMediaWikiConfig {
tag: context.tokenTable[ this.tags.htmlEntity ], tag: context.tokenTable[ this.tags.htmlEntity ],
class: 'cm-mw-html-entity' class: 'cm-mw-html-entity'
}, },
{
tag: context.tokenTable[ this.tags.linkGround ],
class: 'cm-mw-link-ground'
},
{ {
tag: context.tokenTable[ this.tags.linkPageName ], tag: context.tokenTable[ this.tags.linkPageName ],
class: 'cm-mw-link-pagename' class: 'cm-mw-link-pagename'
@ -495,38 +481,10 @@ class CodeMirrorModeMediaWikiConfig {
tag: context.tokenTable[ this.tags.tableCaption ], tag: context.tokenTable[ this.tags.tableCaption ],
class: 'cm-mw-table-caption' class: 'cm-mw-table-caption'
}, },
{
tag: context.tokenTable[ this.tags.templateGround ],
class: 'cm-mw-template-ground'
},
{
tag: context.tokenTable[ this.tags.templateExtGround ],
class: 'cm-mw-template-ext-ground'
},
{
tag: context.tokenTable[ this.tags.templateLinkGround ],
class: 'cm-mw-template-link-ground'
},
{ {
tag: context.tokenTable[ this.tags.templateVariableDelimiter ], tag: context.tokenTable[ this.tags.templateVariableDelimiter ],
class: 'cm-mw-templatevariable-delimiter' class: 'cm-mw-templatevariable-delimiter'
}, },
{
tag: context.tokenTable[ this.tags.template2ExtGround ],
class: 'cm-mw-template2-ext-ground'
},
{
tag: context.tokenTable[ this.tags.template2Ground ],
class: 'cm-mw-template2-ground'
},
{
tag: context.tokenTable[ this.tags.template3ExtGround ],
class: 'cm-mw-template3-ext-ground'
},
{
tag: context.tokenTable[ this.tags.template3Ground ],
class: 'cm-mw-template3-ground'
},
...this.extHighlightStyles ...this.extHighlightStyles
]; ];

View file

@ -33,11 +33,53 @@ class CodeMirrorModeMediaWiki {
this.tokens = []; this.tokens = [];
this.oldTokens = []; this.oldTokens = [];
this.tokenTable = modeConfig.tokenTable; this.tokenTable = modeConfig.tokenTable;
this.registerGroundTokens();
// Dynamically register any tags that aren't already in CodeMirrorModeMediaWikiConfig // Dynamically register any tags that aren't already in CodeMirrorModeMediaWikiConfig
Object.keys( this.config.tags ).forEach( ( tag ) => modeConfig.addTag( tag ) ); Object.keys( this.config.tags ).forEach( ( tag ) => modeConfig.addTag( tag ) );
} }
/**
* Register the ground tokens. These aren't referenced directly in the StreamParser, nor do
* they have a parent Tag, so we don't need them as constants like we do for other tokens.
* See this.makeLocalStyle() for how these tokens are used.
*/
registerGroundTokens() {
[
'mw-ext-ground',
'mw-ext-link-ground',
'mw-ext2-ground',
'mw-ext2-link-ground',
'mw-ext3-ground',
'mw-ext3-link-ground',
'mw-link-ground',
'mw-template-ext-ground',
'mw-template-ext-link-ground',
'mw-template-ext2-ground',
'mw-template-ext2-link-ground',
'mw-template-ext3-ground',
'mw-template-ext3-link-ground',
'mw-template-ground',
'mw-template-link-ground',
'mw-template2-ext-ground',
'mw-template2-ext-link-ground',
'mw-template2-ext2-ground',
'mw-template2-ext2-link-ground',
'mw-template2-ext3-ground',
'mw-template2-ext3-link-ground',
'mw-template2-ground',
'mw-template2-link-ground',
'mw-template3-ext-ground',
'mw-template3-ext-link-ground',
'mw-template3-ext2-ground',
'mw-template3-ext2-link-ground',
'mw-template3-ext3-ground',
'mw-template3-ext3-link-ground',
'mw-template3-ground',
'mw-template3-link-ground'
].forEach( ( ground ) => modeConfig.addToken( ground ) );
}
eatHtmlEntity( stream, style ) { eatHtmlEntity( stream, style ) {
let ok; let ok;
if ( stream.eat( '#' ) ) { if ( stream.eat( '#' ) ) {
@ -67,44 +109,6 @@ class CodeMirrorModeMediaWiki {
makeLocalStyle( style, state, endGround ) { makeLocalStyle( style, state, endGround ) {
let ground = ''; let ground = '';
/**
* List out token names in a comment for search purposes.
*
* Tokens used here include:
* - mw-ext-ground
* - mw-ext-link-ground
* - mw-ext2-ground
* - mw-ext2-link-ground
* - mw-ext3-ground
* - mw-ext3-link-ground
* - mw-link-ground
* - mw-template-ext-ground
* - mw-template-ext-link-ground
* - mw-template-ext2-ground
* - mw-template-ext2-link-ground
* - mw-template-ext3-ground
* - mw-template-ext3-link-ground
* - mw-template-link-ground
* - mw-template2-ext-ground
* - mw-template2-ext-link-ground
* - mw-template2-ext2-ground
* - mw-template2-ext2-link-ground
* - mw-template2-ext3-ground
* - mw-template2-ext3-link-ground
* - mw-template2-ground
* - mw-template2-link-ground
* - mw-template3-ext-ground
* - mw-template3-ext-link-ground
* - mw-template3-ext2-ground
* - mw-template3-ext2-link-ground
* - mw-template3-ext3-ground
* - mw-template3-ext3-link-ground
* - mw-template3-ground
* - mw-template3-link-ground
*
* NOTE: these should be defined in CodeMirrorModeMediaWikiConfig.tokenTable()
* and CodeMirrorModeMediaWikiConfig.highlightStyle()
*/
switch ( state.nTemplate ) { switch ( state.nTemplate ) {
case 0: case 0:
break; break;

View file

@ -148,6 +148,11 @@ const testCases = [
input: 'Soft­hyphen\nzero-widthspace\nnon-breaking space\nnarrownbsp', input: 'Soft­hyphen\nzero-widthspace\nnon-breaking space\nnarrownbsp',
// i18n messages are the keys because we don't stub mw.msg() in this test. // i18n messages are the keys because we don't stub mw.msg() in this test.
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>' 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>'
},
{
title: 'Nested template calls',
input: '{{foo|{{bar|[[Test]]|{{baz|[[Test2]]}}}}}}',
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>'
} }
]; ];
@ -242,7 +247,6 @@ describe( 'CodeMirrorModeMediaWiki', () => {
// Custom tags // Custom tags
'em', 'em',
'error', 'error',
'extGround',
'extNowiki', 'extNowiki',
'extPre', 'extPre',
'extTag', 'extTag',
@ -253,7 +257,6 @@ describe( 'CodeMirrorModeMediaWiki', () => {
'freeExtLinkProtocol', 'freeExtLinkProtocol',
'htmlEntity', 'htmlEntity',
'link', 'link',
'linkGround',
'linkPageName', 'linkPageName',
'nowiki', 'nowiki',
'pageName', 'pageName',
@ -262,14 +265,7 @@ describe( 'CodeMirrorModeMediaWiki', () => {
'skipFormatting', 'skipFormatting',
'strong', 'strong',
'tableCaption', 'tableCaption',
'templateGround', 'templateVariableDelimiter'
'templateExtGround',
'templateLinkGround',
'templateVariableDelimiter',
'template2ExtGround',
'template2Ground',
'template3ExtGround',
'template3Ground'
] ); ] );
} ); } );
} ); } );