MediaWiki:Gadget-CodeLinks.js
Asayış
(Karber:Balyozxane/Gadget-CodeLinks.js ra kırışiyaya)
Note: Qeydi ra dıme, gani viriya cıgeyrayoği pak bo ke vurnayışi bıvêniyê.
- Gışta şıma ke niya ro gocega Firefox / Safari: Shift ser, bıtıknê ra newe ra bar kerên ya zi Ctrl-F5 ya zi Ctrl-R bıtıknê (seba Mac ra ⌘-R).
- Google Chrome: Ctrl-Shift-R ro nê. (seba Mac ra ⌘-Shift-R)
- Internet Explorer / Edge: Ctrl ke niyo ro cı, Newe ke bıtıknê ya zi Ctrl-F5 bıkerê.
- Opera: Ctrl-F5 bıtıknê.
/*jshint undef:true, latedef:true */
/*global mw, jQuery */
jQuery(function CodeLinksIIFE() {
'use strict';
// by John Gruber, from https://daringfireball.net/2010/07/improved_regex_for_matching_urls
var URLRegExp = /\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/i;
function processComment(node) {
var wikilinkMatch, templateMatch, URLMatch,
textNode = node.firstChild; // always a text node.
while (
(wikilinkMatch = /\[\[([^|{}\[\]\n]+)?(?:\|.*?)?]]/.exec(textNode.data))
|| (templateMatch = /(\{\{(?:#invoke:)?)([^|{}\[\]\n#]+)(?=\||}})/i.exec(textNode.data))
|| (URLMatch = URLRegExp.exec(textNode.data))
) {
var link = document.createElement('a'),
start = (wikilinkMatch || templateMatch || URLMatch).index,
linkText;
link.classList.add("code-link");
if (URLMatch) {
var URL = URLMatch[0];
link.href = URL;
linkText = URL;
} else {
var fullPageName;
if (wikilinkMatch) {
linkText = wikilinkMatch[0];
fullPageName = wikilinkMatch[1];
} else if (templateMatch) {
var prefix = templateMatch[1],
pageName = templateMatch[2];
linkText = pageName;
fullPageName = (prefix === '{{#invoke:' ? 'Modul:' : 'Şablon:')
+ pageName;
link.title = fullPageName;
start += prefix.length;
}
link.href = mw.util.getUrl(fullPageName);
}
var beforeLink = textNode.data.substring(0, start),
afterLink = textNode.data.substring(start + linkText.length);
textNode.data = afterLink;
link.appendChild(document.createTextNode(linkText));
node.insertBefore(link, textNode);
node.insertBefore(document.createTextNode(beforeLink), link);
// ensure all matches are null at beginning of loop body; is this necessary?
wikilinkMatch = templateMatch = URLMatch = null;
}
}
function each(coll, walk) {
return Array.prototype.forEach.call(coll, walk);
}
var commentClasses = [ 'c', 'c1', 'cm' ];
each(document.getElementsByClassName('mw-highlight'), function (codeBlock) {
each(commentClasses, function (commentClass) {
each(codeBlock.getElementsByClassName(commentClass), processComment);
});
});
// Link module names after `require` and `mw.loadData`, and tracking template
// names after `require("Module:debug").track`.
var copyArray = Array.from ? Array.from.bind(Array) :
function copyArray(array) {
return Array.prototype.slice.call(array);
};
var classes = {
identifier: "n", functionName: "nb",
singleQuoteString: "s1", doubleQuoteString: "s2",
};
var trackingTemplateElements = [], moduleNames = [], dataModuleNames = [];
var functionNames = document.getElementsByClassName(classes.functionName);
Array.prototype.forEach.call(functionNames, function (functionName) {
var text = functionName.firstChild.nodeValue;
if (text !== "require")
return;
var next = functionName.nextElementSibling;
var nextText = next && next.firstChild && next.firstChild.nodeValue;
var hasParenthesis = nextText === "(";
if (hasParenthesis) {
next = next.nextElementSibling;
nextText = next && next.firstChild && next.firstChild.nodeValue;
}
var classList = next.classList;
if (!(classList.contains(classes.singleQuoteString)
|| classList.contains(classes.doubleQuoteString)))
return;
var string = next;
var stringValue = nextText;
if (!stringValue)
return;
next = next.nextElementSibling;
nextText = next && next.firstChild && next.firstChild.nodeValue;
if (hasParenthesis && nextText && nextText[0] !== ")")
return;
moduleNames.push(string);
if (hasParenthesis ? nextText === ")." : nextText === "."
&& (/^["']mod(?:ul)?(e)?:(.+)["']$/i.exec(stringValue) || [])[1] === "debug") {
next = next.nextElementSibling;
nextText = next && next.firstChild && next.firstChild.nodeValue;
if (nextText !== "track")
return;
next = next.nextElementSibling;
nextText = next && next.firstChild && next.firstChild.nodeValue;
var trackWithParenthesis = false;
if (nextText === "(") {
next = next.nextElementSibling;
trackWithParenthesis = true;
}
classList = next.classList;
if (!(classList.contains(classes.singleQuoteString)
|| classList.contains(classes.doubleQuoteString)))
return;
nextText = next && next.firstChild && next.firstChild.nodeValue;
if (!nextText)
return;
// If there was a parenthesis on one side – `track("...")` rather than
// `track "..."` – make sure there's a matching parenthesis on the other side.
if (trackWithParenthesis) {
var after = next.nextElementSibling;
var afterText = after && after.firstChild && after.firstChild.nodeValue;
if (afterText !== ")")
return;
}
trackingTemplateElements.push(next);
}
});
var strings = copyArray(document.getElementsByClassName(classes.singleQuoteString))
.concat(copyArray(document.getElementsByClassName(classes.doubleQuoteString)));
Array.prototype.forEach.call(strings, function (string) {
if (moduleNames.indexOf(string) !== -1 || trackingTemplateElements.indexOf(string) !== -1)
return;
var stringValue = string.firstChild.nodeValue;
if (!/^["'](?:module|modul|mod):/i.test(stringValue))
return;
var prev = string.previousElementSibling;
var prevText = prev && prev.firstChild && prev.firstChild.nodeValue;
if (prevText === "(") {
var next = string.nextElementSibling;
var nextText = next && next.firstChild && next.firstChild.nodeValue;
if (!(nextText && nextText[0] === ")"))
return;
prev = prev.previousElementSibling;
prevText = prev && prev.firstChild && prev.firstChild.nodeValue;
}
if (prevText !== "loadData")
return;
prev = prev.previousElementSibling;
prevText = prev && prev.firstChild && prev.firstChild.nodeValue;
if (prevText !== ".")
return;
prev = prev.previousElementSibling;
prevText = prev && prev.firstChild && prev.firstChild.nodeValue;
if (prevText !== "mw")
return;
dataModuleNames.push(string);
});
if (moduleNames.length > 0 || trackingTemplateElements.length > 0
|| dataModuleNames.length > 0) {
mw.loader.using("mediawiki.util").done(function () {
function addLink(element, page) {
if (!(element instanceof Element))
throw new TypeError("Expected Element object");
var link = document.createElement("a");
link.href = mw.util.getUrl(page);
// put text node from element inside link
var firstChild = element.firstChild;
if (!(firstChild instanceof Text))
throw new TypeError("Expected Text object");
link.appendChild(firstChild);
element.appendChild(link); // put link inside syntax-highlighted string
}
// Link module names to module pages, or to the section in the Scribunto
// manual.
moduleNames.concat(dataModuleNames).forEach(function (module) {
var link = document.createElement("a");
var stringValue = module.firstChild.nodeValue;
var moduleName = stringValue.substring(1, stringValue.length - 1);
var linkPage = /^mod(?:ul)(?:e)?:/i.test(moduleName)
? moduleName
: "mw:Extension:Scribunto/Lua reference manual#" + moduleName;
addLink(module, linkPage);
});
// Link tracking templates to [[Special:WhatLinksHere]].
trackingTemplateElements.forEach(function (trackingTemplate) {
var text = trackingTemplate.firstChild && trackingTemplate.firstChild.nodeValue;
if (!text)
return;
var trackingCode = text.substring(1, text.length - 1);
addLink(trackingTemplate, "Bağse:GreyNaySeraşıno/Şablon:tracking/" + trackingCode);
});
});
}
});