User:MusikAnimal/dablinkwarn.js

(function (mw, $) {   var $textarea = $('#wpTextbox1'),        $editor = $textarea,        api = new mw.Api;

function addKeyListener { $editor.off('keyup.dablinkwarn').on('keyup.dablinkwarn', function (e) {           if (e.key === ']') {                var cursorPosition = e.target.selectionStart,                    context = $textarea.val.substring(0, cursorPosition),                    matches = /.*(\[\[(.*?)(?:\|.*?]]|]]))$/.exec(context);

if (matches && matches.length) { // We always want the last match. var pageTitle = matches[matches.length - 1].trim, // Also keep track of the start of the link so we can do replacements later. linkWikitext = matches[matches.length - 2]; var linkPosition = context.length - linkWikitext.length;

api.get({                       action: 'query',                        titles: pageTitle,                        prop: 'pageprops',                        ppprop: 'disambiguation',                        list: 'prefixsearch',                        pssearch: pageTitle,                        pslimit: 5,                        formatversion: 2,                    }).then(function (resp) {                        if (resp.query.pages && resp.query.pages[0].pageprops && resp.query.pages[0].pageprops.disambiguation === '' ) {                           var alternatives = resp.query.prefixsearch.map(function (elem) { return elem.title; }).filter(function (title) { return title !== pageTitle; }),                               $container = $(' '),                                $helpLink = $('').prop('href', new mw.Title('Disambiguation', 4).getUrl)                                    .prop('target', '_blank')                                    .text('disambiguation page'),                                $pageLink = $('').prop('href', new mw.Title(pageTitle).getUrl)                                    .prop('target', '_blank')                                    .text(pageTitle),                                $message = $(' ').append('You linked to the page "')                                    .append($pageLink)                                    .append('" which is a ')                                    .append($helpLink)                                    .append('. ');                           $container.append($message);

if (alternatives.length) { $message.append('Did you mean one of the following?'); var $links = alternatives.map(function (title) {                                       return $('').prop('href', new mw.Title(title).getUrl)                                            .prop('target', '_blank')                                            .text(title);                                    }), $altList = $(''); $links.forEach($link => {                                   $altList.append( $('').append($link) );                                   $link.one('click', function (e) { if ($textarea.val.substring(linkPosition, linkPosition + linkWikitext.length) === linkWikitext) { e.preventDefault; var newLinkWikitext = linkWikitext.replace(/(\[\[.*?(\|.*?]]|]]))/, '[[' + $link.text + '$2'); $textarea.val(                                               $textarea.val.substring(0, linkPosition)                                                + newLinkWikitext                                                + $textarea.val.substring(linkPosition + linkWikitext.length)                                            ); $(e.target).parents('.mw-notification').trigger('click'); }                                   });                                });                                $container.append($altList); }

mw.notify($container, {                               autoHideSeconds: 'long',                                type: 'warn',                            }); }                   });                }            }        });    }

function addListeners { mw.hook('ext.CodeMirror.switch').add(function (_enabled, $target) {           $editor.off('keyup.dablinkwarn');            $editor = $target;            addKeyListener;        }); addKeyListener; }

// TODO: Only do this for inexperienced editors // TODO: Only target the mainspace (userspace enabled for safer testing purposes) // TODO: Only for desktop? if ([0, 2].includes(mw.config.get('wgNamespaceNumber'))       && ['edit', 'submit'].includes(mw.config.get('wgAction'))    ) { addListeners; } })(mediaWiki, jQuery);