Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.
- Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
- Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
- Internet Explorer/Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
- Opera: Strg+F5
//Dokumentation unter [[Benutzer:Schnark/js/linkUnlinked]] <nowiki>
/*global mediaWiki*/
(function ($, mw, libs) {
"use strict";
var style = 'color: inherit !important; text-decoration: inherit !important; font: inherit !important;',
cssClass = 'schnark-linkUnlinked-link',
/* "Applications are free to use any of these noncharacter code points internally but should
''never'' attempt to exchange them." (Unicode Standard, 16.7 Noncharacters) */
uniqueChar = '\uFDD0',
uniqueRe = new RegExp (uniqueChar + '(\\d+)' + uniqueChar, 'g'),
protoRe = new RegExp ('^(?:' + mw.config.get('wgUrlProtocols') + ')'),
linkRe;
function getProtos (tags, rel) {
var protos = mw.config.get('wgUrlProtocols').split('|'), relPos, i;
function insertUnique (c) {
return c + tags;
}
if (!rel) {
relPos = protos.indexOf('\\/\\/');
if (relPos !== -1) {
protos.splice(relPos, 1);
}
}
for (i = 0; i < protos.length; i++) {
protos[i] = protos[i].replace(/[^\\]|\\./g, insertUnique); //]/// <- dumme Syntaxhervorhebung
}
return protos.join('|');
}
function makeLinkRe () {
var pZs = '\u0020\u00A0\u1680\u180E\u2000-\u200A\u202F\u205F\u3000',
tags = '(?:' + uniqueChar + '\\d+' + uniqueChar + ')*',
wikilinkChar = '[^\\[\\]\\|\\n\\{\\}]',
extlinkChar = '[^\\[\\]"\u0000-\u0020\u007F' + pZs + ']',
wikilink = '\\[' + tags + '\\[(' + wikilinkChar + '+)(?:\\|[^\\[\\]\\n]*)?(?:\\]' + tags + '\\]|\\|)',
extlink = '\\[' + tags + '((?:' + getProtos(tags, true) + ')' + extlinkChar + '+)' +
'(?:[' + pZs + ']*[^\\]\u0000-\u0008\u000a-\u001F]*)?\\]',
extlink2 = '\\b((?:' + getProtos(tags) + ')' + extlinkChar + '+)',
isbn = '\\bI' + tags + 'S' + tags + 'B' + tags + 'N' + tags + '\\s+' + tags +
'((?:9' + tags + '7' + tags + '[89]' + tags + '[ -]?' + tags + ')?' +
'(?:[0-9]' + tags + '[ -]?' + tags + '){9}[0-9Xx]' + tags + ')\\b';
return new RegExp(wikilink + '|' + extlink + '|' + extlink2 + '|' + isbn, 'gi');
}
function rel2abs (rel, base) {
if (rel.charAt(0) === '/') {
return base + rel.replace(/\/(#|$)/, '$1');
}
if (rel.indexOf('../') !== 0) {
return rel.replace(/^:/, '');
}
while (rel.indexOf('../') === 0 && base.indexOf('/') !== -1) {
rel = rel.slice(3);
base = base.replace(/\/[^\/]*$/, '');
}
return base + '/' + rel.replace(/\/(#|$)/, '$1');
}
function wikilinkToUrl (link) {
try {
link = decodeURIComponent(link);
} catch (e) {}
link = rel2abs(link, mw.config.get('wgPageName'));
if (/[<>]|\.\.\//.test(link)) {
return false;
}
if (link.indexOf('&') > -1) { //fix HTML entities
//NOTE this is safe because link can't contain <>
link = $('<span>').html(link).text();
}
if (link.charAt(0) === '#') {
return '#' + mw.util.escapeIdForLink(link.slice(1));
}
return mw.util.getUrl(link);
}
function normalize (link) {
link = link.replace(uniqueRe, '');
link = link.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/&/g, '&');
link = link.replace(/<!--.*?-->/g, '');
link = link.replace(/<!--.*$/, '');
return link;
}
function strip (html) {
var tags = [],
stripped = html.replace(/<\/?\w+(?:\s+\w+(?:="[^<>"\n]*")?)*(?:\s*\/)?>|<!--.*?-->/g, function (tag) {
tags.push(tag);
return uniqueChar + String(tags.length - 1) + uniqueChar;
});
return [stripped, tags];
}
function unstrip (stripped, tags) {
return stripped.replace(uniqueRe, function (all, n) {
return tags[Number(n)];
});
}
function change (html, changeF) {
if (/<a\b/.test(html)) {
return false;
}
if (html.indexOf(uniqueChar) > -1) {
return false;
}
var stripped, tags, ret = strip(html);
stripped = ret[0];
tags = ret[1];
if (/[<>]/.test(stripped)) { //" kann vorkommen!
return false;
}
stripped = changeF(stripped);
html = unstrip(stripped, tags);
if (html.indexOf(uniqueChar) > -1) {
return false;
}
return html;
}
function replaceLinks (text) {
return text.replace(linkRe, function (all, wikilink, extlink, extlink2, isbn) {
var link, open, close, pre = '', post = '', result;
if (wikilink) {
link = normalize(wikilink);
if (protoRe.test(link)) { //externer Link in doppelten eckigen Klammern
pre = '[';
all = all.slice(1);
result = linkRe.exec(all);
if (result && result[2]) {
post = all.slice(result[0].length);
all = result[0];
link = normalize(result[2]);
link = link.replace(/[<>].*$/, '');
} else {
link = false;
}
} else {
link = wikilinkToUrl(link);
}
} else if (extlink) {
link = normalize(extlink);
link = link.replace(/[<>].*$/, '');
} else if (extlink2) {
link = normalize(extlink2);
link = link.replace(/[<>].*$/, '');
if (link.indexOf('(') === -1) {
link = link.replace(/[,;.:!?)]+$/, '');
post = (/[,.:!?)]*$/).exec(all)[0]; //FIXME müsste auch Ersetzungen von normalize beachten und ; entfernen
} else {
link = link.replace(/[,;.:!?]+$/, '');
post = (/[,.:!?]*$/).exec(all)[0]; //FIXME müsste auch Ersetzungen von normalize beachten und ; entfernen
}
if (post.length) {
all = all.slice(0, -post.length);
}
} else {
link = normalize(isbn).replace(/[ \-]/g, '').replace(/x/, 'X');
link = wikilinkToUrl('Special:Booksources/' + link);
}
if (!link) {
return pre + all + post;
}
open = '<a href="' + mw.html.escape(link) + '" class="' + cssClass + '">';
close = '</a>';
return (pre + open + all.replace(uniqueRe, function (unique) {
return close + unique + open;
}) + close + post).replace(/<a [^>]+>(\s*)<\/a>/g, '$1');
});
}
function changeHtml (html) {
html = html.replace(/<a name="([^"]*)"><\/a>/g, '<span id="$1"></span>'); //Den Mist von [[phab:T182292]] korrigieren
return change(html, replaceLinks);
}
function changeElements ($el) {
$el.each(function () {
var oldHtml = this.innerHTML, newHtml = changeHtml(oldHtml);
if (newHtml && oldHtml !== newHtml) {
this.innerHTML = newHtml;
}
});
}
function linkDiff ($diff) {
changeElements($diff.find('td.diff-context, td.diff-addedline, td.diff-deletedline'));
}
function linkSyntax ($content) {
changeElements($content.find('.mw-highlight pre, pre.source-javascript, pre.source-css'));
}
function linkSchnarkDiff ($diff) {
changeElements($diff.find('ins, del, span'));
}
function init () {
linkRe = makeLinkRe();
mw.util.addCSS('.' + cssClass + '{' + style + '}');
mw.hook('wikipage.diff').add(linkDiff);
if (/\.(?:js|css)$/.test(mw.config.get('wgTitle')) && [2, 8].indexOf(mw.config.get('wgNamespaceNumber')) > -1) {
mw.hook('wikipage.content').add(linkSyntax);
}
mw.hook('userjs.schnark-diff').add(linkSchnarkDiff);
if (libs.qunit) {
libs.qunit.rel2abs = rel2abs;
libs.qunit.wikilinkToUrl = wikilinkToUrl;
libs.qunit.strip = strip;
libs.qunit.unstrip = unstrip;
libs.qunit.changeHtml = changeHtml;
libs.qunit.changeElements = changeElements;
}
}
mw.loader.using('mediawiki.util').then(init);
})(jQuery, mediaWiki, mediaWiki.libs);
//</nowiki>