mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/SyntaxHighlight_GeSHi
synced 2024-11-13 17:50:37 +00:00
Fix bugs in link generation
* Use mw.Title so that template links work for templates outside template namespace, and so that titles are normalized. * Use recursion instead of while loop so that both the segments before and after the inserted link are searched for further linking possibilities. Among other cases, this fixes the case where a template link before a wikilink (on the same line) was not working. This also avoids infinite iteration if mw.Title.newFromText() failed to create a valid Title object. Bug: T368166 Bug: T374693 Change-Id: I4d485340928b81df26ca035874422fdb5930710f
This commit is contained in:
parent
16538948ae
commit
341cd2bc37
|
@ -8,53 +8,59 @@ $( () => {
|
|||
// 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.
|
||||
const wikilinkRegExp = /\[\[([^|{}[\]\n]+)?(?:\|.*?)?]]/;
|
||||
const templateRegExp = /\{\{([^|{}[\]\n#]+)(?=\||}})/;
|
||||
|
||||
while (
|
||||
( wikilinkMatch = /\[\[([^|{}[\]\n]+)?(?:\|.*?)?]]/.exec( textNode.data ) ) ||
|
||||
( templateMatch = /\{\{([^|{}[\]\n#]+)(?=\||}})/i.exec( textNode.data ) ) ||
|
||||
function processComment( textNode, node ) {
|
||||
let wikilinkMatch, templateMatch, URLMatch;
|
||||
|
||||
if (
|
||||
( wikilinkMatch = wikilinkRegExp.exec( textNode.data ) ) ||
|
||||
( templateMatch = templateRegExp.exec( textNode.data ) ) ||
|
||||
( URLMatch = URLRegExp.exec( textNode.data ) )
|
||||
) {
|
||||
const link = document.createElement( 'a' );
|
||||
let start = ( wikilinkMatch || templateMatch || URLMatch ).index;
|
||||
let linkText;
|
||||
let linkText, title;
|
||||
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 );
|
||||
} else if ( wikilinkMatch ) {
|
||||
linkText = wikilinkMatch[ 0 ];
|
||||
title = mw.Title.newFromText( wikilinkMatch[ 1 ] );
|
||||
} else if ( templateMatch ) {
|
||||
const pageName = templateMatch[ 1 ];
|
||||
start += 2; // opening braces "{{"
|
||||
linkText = pageName;
|
||||
title = mw.Title.newFromText( pageName, 10 );
|
||||
}
|
||||
if ( title ) {
|
||||
link.href = mw.util.getUrl( title.toText() );
|
||||
link.title = title.toText();
|
||||
}
|
||||
if ( link.href ) {
|
||||
const textBeforeLink = textNode.data.slice( 0, Math.max( 0, start ) ),
|
||||
textAfterLink = textNode.data.slice( Math.max( 0, start + linkText.length ) );
|
||||
|
||||
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 );
|
||||
textNode.data = textAfterLink;
|
||||
link.appendChild( document.createTextNode( linkText ) );
|
||||
node.insertBefore( link, textNode );
|
||||
const beforeTextNode = node.insertBefore( document.createTextNode( textBeforeLink ), link );
|
||||
processComment( beforeTextNode, node );
|
||||
processComment( textNode, node );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const commentClasses = [ 'c', 'c1', 'cm' ];
|
||||
Array.from( document.getElementsByClassName( 'mw-highlight' ) ).forEach( ( codeBlock ) => {
|
||||
commentClasses.forEach( ( commentClass ) => {
|
||||
Array.from( codeBlock.getElementsByClassName( commentClass ) ).forEach( processComment );
|
||||
Array.from( codeBlock.getElementsByClassName( commentClass ) ).forEach( ( node ) => {
|
||||
processComment( node.firstChild, node );
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
|
||||
|
|
Loading…
Reference in a new issue