mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/SyntaxHighlight_GeSHi
synced 2024-11-30 17:14:55 +00:00
Enable clicking on wikilinks and external links in highlighted code
It's common practise to use [[wikilink]] syntax to mention page names in comments of JS/CSS/Scribunto code where the links ordinarily don't work. Using JavaScript to actually make the syntax clickable makes navigation easier. {{Templates links}} and external links are also supported. Bug: T368166 Change-Id: I999937c1f6303ecc64adb6285e73a9ce10f67bd8
This commit is contained in:
parent
4127ae3181
commit
7fa3abe91e
|
@ -38,9 +38,10 @@
|
||||||
"pygments.wrapper.less"
|
"pygments.wrapper.less"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ext.pygments.linenumbers": {
|
"ext.pygments.view": {
|
||||||
"scripts": [
|
"scripts": [
|
||||||
"pygments.linenumbers.js"
|
"pygments.linenumbers.js",
|
||||||
|
"pygments.links.js"
|
||||||
],
|
],
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"mediawiki.util"
|
"mediawiki.util"
|
||||||
|
|
|
@ -196,10 +196,7 @@ class SyntaxHighlight extends ExtensionTagHandler implements
|
||||||
|
|
||||||
// Register CSS
|
// Register CSS
|
||||||
$parser->getOutput()->addModuleStyles( self::getModuleStyles() );
|
$parser->getOutput()->addModuleStyles( self::getModuleStyles() );
|
||||||
if ( !empty( $args['linelinks'] ) ) {
|
$parser->getOutput()->addModules( [ 'ext.pygments.view' ] );
|
||||||
$parser->getOutput()->addModules( [ 'ext.pygments.linenumbers' ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result['html'];
|
return $result['html'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,7 +595,7 @@ class SyntaxHighlight extends ExtensionTagHandler implements
|
||||||
$out = $status->getValue();
|
$out = $status->getValue();
|
||||||
|
|
||||||
$parserOutput->addModuleStyles( self::getModuleStyles() );
|
$parserOutput->addModuleStyles( self::getModuleStyles() );
|
||||||
$parserOutput->addModules( [ 'ext.pygments.linenumbers' ] );
|
$parserOutput->addModules( [ 'ext.pygments.view' ] );
|
||||||
$parserOutput->setText( $out );
|
$parserOutput->setText( $out );
|
||||||
|
|
||||||
// Inform MediaWiki that we have parsed this page and it shouldn't mess with it.
|
// Inform MediaWiki that we have parsed this page and it shouldn't mess with it.
|
||||||
|
|
61
modules/pygments.links.js
Normal file
61
modules/pygments.links.js
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/**
|
||||||
|
* Adapted from https://en.wiktionary.org/wiki/MediaWiki:Gadget-CodeLinks.js
|
||||||
|
* Original authors: Kephir, Erutuon
|
||||||
|
* License: CC-BY-SA 4.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
$( () => {
|
||||||
|
// by John Gruber, from https://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
||||||
|
const URLRegExp = /\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()[\]{};:'".,<>?«»“”‘’]))/i;
|
||||||
|
|
||||||
|
function processComment( node ) {
|
||||||
|
let wikilinkMatch, templateMatch, URLMatch;
|
||||||
|
const textNode = node.firstChild; // always a text node.
|
||||||
|
|
||||||
|
while (
|
||||||
|
( wikilinkMatch = /\[\[([^|{}[\]\n]+)?(?:\|.*?)?]]/.exec( textNode.data ) ) ||
|
||||||
|
( templateMatch = /\{\{([^|{}[\]\n#]+)(?=\||}})/i.exec( textNode.data ) ) ||
|
||||||
|
( URLMatch = URLRegExp.exec( textNode.data ) )
|
||||||
|
) {
|
||||||
|
const link = document.createElement( 'a' );
|
||||||
|
let start = ( wikilinkMatch || templateMatch || URLMatch ).index;
|
||||||
|
let linkText;
|
||||||
|
link.classList.add( 'code-link' );
|
||||||
|
|
||||||
|
if ( URLMatch ) {
|
||||||
|
const URL = URLMatch[ 0 ];
|
||||||
|
link.href = URL;
|
||||||
|
linkText = URL;
|
||||||
|
} else {
|
||||||
|
let fullPageName;
|
||||||
|
if ( wikilinkMatch ) {
|
||||||
|
linkText = wikilinkMatch[ 0 ];
|
||||||
|
fullPageName = wikilinkMatch[ 1 ];
|
||||||
|
} else if ( templateMatch ) {
|
||||||
|
const pageName = templateMatch[ 1 ];
|
||||||
|
linkText = pageName;
|
||||||
|
fullPageName = mw.config.get( 'wgFormattedNamespaces' )[ 10 ] + ':' + pageName;
|
||||||
|
link.title = fullPageName;
|
||||||
|
start += 2; // opening braces "{{"
|
||||||
|
}
|
||||||
|
link.href = mw.util.getUrl( fullPageName );
|
||||||
|
}
|
||||||
|
|
||||||
|
const beforeLink = textNode.data.slice( 0, Math.max( 0, start ) ),
|
||||||
|
afterLink = textNode.data.slice( Math.max( 0, start + linkText.length ) );
|
||||||
|
|
||||||
|
textNode.data = afterLink;
|
||||||
|
link.appendChild( document.createTextNode( linkText ) );
|
||||||
|
node.insertBefore( link, textNode );
|
||||||
|
node.insertBefore( document.createTextNode( beforeLink ), link );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const commentClasses = [ 'c', 'c1', 'cm' ];
|
||||||
|
Array.from( document.getElementsByClassName( 'mw-highlight' ) ).forEach( ( codeBlock ) => {
|
||||||
|
commentClasses.forEach( ( commentClass ) => {
|
||||||
|
Array.from( codeBlock.getElementsByClassName( commentClass ) ).forEach( processComment );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
} );
|
Loading…
Reference in a new issue