Benutzer:Schnark/js/bkl-check.js

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen

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/bkl-check]] <nowiki>
/*global mediaWiki*/
(function ($, mw) {
"use strict";
var config = {
	onlyCheckMainNS: false,
	onlyCheckCurrent: false,
	dontCheckSpecial: false,
	onlyMarkMainNS: true,
	maxTitles: 50
}, cachedLinks = false, cachedLinksContent, namespaceRe, hasOwn = Object.prototype.hasOwnProperty;

function makeStyle (c, text, color) {
	return '.' + c + ' {' +
			'background-color: ' + (color || 'rgba(255, 0, 0, .43)') +
		'}' +
		'.' + c + '::after {' +
			'content: "' + text.replace(/([\\"])/g, '\\$1') + '";' +
			'font-size: 70%;' +
			'vertical-align: super;' +
			'line-height: 0;' +
		'}' +
		'@media print {' +
			'.' + c + ' {' +
				'background-color: transparent;' +
			'}' +
			'.' + c + '::after {' +
				'content: none;' +
			'}' +
		'}';
}

function makeConfig (data, useDisambig) {
	var i, css = '', cats = {};
	for (i = 0; i < data.length; i++) {
		css += makeStyle(data[i].className, data[i].tag, data[i].color);
		cats[mw.config.get('wgFormattedNamespaces')[14] + ':' + data[i].category.replace(/_/g, ' ')] = {
			className: data[i].className,
			titleAppend: ' (' + data[i].title + ')'
		};
	}
	return {css: css, cats: cats, useDisambig: useDisambig};
}

function getConfig (project) {
	switch (project) {
	case 'my_wiki':
	case 'dewiki':
		return makeConfig([
			{category: 'Begriffsklärung', title: 'Begriffsklärungsseite', tag: 'BKL', className: 'bkl-link'},
			{category: 'Wikipedia:Falschschreibung', title: 'Falschschreibung', tag: 'FS', className: 'fs-link'},
			{category: 'Wikipedia:Obsolete Schreibung', title: 'Obsolete Schreibung', tag: 'OS', className: 'os-link'}
		], project === 'dewiki');
	case 'enwiki':
		return makeConfig([
			{category: 'All disambiguation pages', title: 'disambiguation page', tag: 'DAB', className: 'dab-link'}
		], true);
	default:
		mw.log.warn('No configuration for bkl-check.js for this project!');
		return makeConfig([], false);
	}
}

function getTitleFromLink (a) {
	//return a.title || '';
	var href = $(a).attr('href') || '', path = mw.config.get('wgArticlePath').replace(/\$1/, '');
	if (href.indexOf(path) !== 0) {
		path = location.origin + path; //mit absoluter URL noch mal probieren
	}
	if (href.indexOf(path) !== 0) {
		return '';
	}
	href = href.slice(path.length);
	href = href.replace(/#.*/, '');
	if (href.indexOf('?') > -1) {
		return '';
	}
	try {
		href = decodeURIComponent(href);
	} catch (e) {
	}
	return href.replace(/_/g, ' ');
}

function clearLinks () {
	cachedLinks = false;
}
function getLinks ($content, mwDisambig) {
	if (!cachedLinks || $content !== cachedLinksContent) {
		if (['edit', 'submit'].indexOf(mw.config.get('wgAction')) !== -1 && $content.find('#wikiPreview').length === 1) {
			$content = $content.find('#wikiPreview');
		}
		cachedLinks = mwDisambig ? $content.find('a.mw-disambig') : $content.find('a').not('.new, .image, .external');
		cachedLinksContent = $content;
	}
	return cachedLinks;
}

function getNamespaceRe () {
	var ns, ids, n, main;
	if (!namespaceRe) {
		ns = [];
		ids = mw.config.get('wgNamespaceIds');
		main = mw.config.get('wgContentNamespaces');
		for (n in ids) {
			if (hasOwn.call(ids, n) && main.indexOf(ids[n]) === -1) {
				ns.push(mw.util.escapeRegExp(n).replace(/_/g, '[ _]+'));
			}
		}
		namespaceRe = new RegExp('^(?:' + ns.join('|') + '):', 'i');
	}
	return namespaceRe;
}

function getTitles ($content, mwDisambig) {
	var titles = [], re;
	if (config.onlyMarkMainNS) {
		re = getNamespaceRe();
	}
	getLinks($content, mwDisambig).each(function () {
		var title = getTitleFromLink(this);
		if (title !== '' && titles.indexOf(title) === -1 && (!config.onlyMarkMainNS || !re.test(title))) {
			titles.push(title);
		}
	});
	return titles;
}

function callWithContinue (query, callback, done, queryContinue) {
	$.getJSON(mw.util.wikiScript('api'), $.extend({}, query, queryContinue))
		.then(function (json) {
			if (json && json.query) {
				callback(json.query);
			}
			if (json && json['continue']) {
				callWithContinue(query, callback, done, json['continue']);
			} else {
				done();
			}
		}, function () {
			done();
		});
}

function getCategoryList () {
	var cats = [], cat;
	for (cat in config.cats) {
		if (hasOwn.call(config.cats, cat)) {
			cats.push(cat);
		}
	}
	return cats.join('|');
}

function getQueryForView () {
	var query = {
		action: 'query',
		prop: 'categories',
		pageids: mw.config.get('wgArticleId'),
		generator: 'links',
		gpllimit: 'max',
		cllimit: 'max',
		clcategories: getCategoryList(),
		redirects: true,
		format: 'json',
		formatversion: 2
	};
	if (config.onlyMarkMainNS) {
		query.gplnamespace = mw.config.get('wgContentNamespaces').join('|');
	}
	return query;
}

function getQueryForPreview (titles) {
	return {
		action: 'query',
		prop: 'categories',
		titles: titles,
		clcategories: getCategoryList(),
		cllimit: 'max',
		redirects: true,
		format: 'json',
		formatversion: 2
	};
}

function getTaggedPagesFromApi (titles, callback, done) {
	if (titles) {
		if (titles.length <= config.maxTitles) {
			callWithContinue(getQueryForPreview(titles.join('|')), callback, done);
		} else {
			callWithContinue(getQueryForPreview(titles.splice(0, config.maxTitles).join('|')), callback, function () {
				getTaggedPagesFromApi(titles, callback, done);
			});
		}
	} else {
		callWithContinue(getQueryForView(), callback, done);
	}
}

function getTaggedPages (titles, callback) {
	var /*normalizations = {},*/ redirects = {}, cats = {}, foundAny = false;
	function addData (query) {
		var i, page;
		/*if (query.normalized) {
			for (i = 0; i < query.normalized.length; i++) {
				normalizations[query.normalized[i].from] = query.normalized[i].to;
			}
		}*/
		if (query.redirects) {
			for (i = 0; i < query.redirects.length; i++) {
				redirects[query.redirects[i].from] = query.redirects[i].to;
			}
		}
		if (query.pages) {
			for (i = 0; i < query.pages.length; i++) {
				page = query.pages[i];
				if (
					page.missing || !page.categories ||
					(config.onlyMarkMainNS && mw.config.get('wgContentNamespaces').indexOf(page.ns) === -1)
				) {
					continue;
				}
				cats[page.title] = page.categories[0].title;
				foundAny = true;
			}
		}
	}

	if (titles) {
		if (titles.length === 0) {
			return;
		}
		titles.sort();
	}
	getTaggedPagesFromApi(titles, addData, function () {
		var t;
		if (foundAny) {
			for (t in redirects) {
				if (hasOwn.call(redirects, t)) {
					cats[t] = cats[redirects[t]];
				}
			}
			/*for (t in normalizations) {
				if (hasOwn.call(normalizations, t)) {
					cats[t] = cats[normalizations[t]];
				}
			}*/
			callback(cats);
		}
	});
}

function markLink (a, cats) {
	var title = getTitleFromLink(a);
	if (cats[title]) {
		$(a).wrapInner(mw.html.element('span', {
			'class': config.cats[cats[title]].className,
			title: a.title + config.cats[cats[title]].titleAppend
		}, ''));
	}
}

function getClassesSelector () {
	var c, classes = [];
	for (c in config.cats) {
		if (hasOwn.call(config.cats, c)) {
			classes.push('.' + config.cats[c].className);
		}
	}
	return classes.join(',');
}

function run ($content) {
	var titles = false, selector = getClassesSelector(), isPreview, isSpecial, isOld, isDynamic;
	if (!selector || $content.find(selector).length) {
		//schon markierte Links
		return;
	}
	isPreview = ['edit', 'submit'].indexOf(mw.config.get('wgAction')) > -1;
	isSpecial = mw.config.get('wgNamespaceNumber') === -1;
	isOld = mw.config.get('wgCurRevisionId') !== mw.config.get('wgRevisionId');
	isDynamic = !isPreview && $content.attr('id') !== 'mw-content-text';
	if (!isSpecial && !isDynamic && config.useDisambig && $('.mw-disambig').length === 0) {
		//wenn MW keine gefunden hat, dann gibt es keine
		return;
	}
	clearLinks();
	if (isPreview || isSpecial || isOld || isDynamic) {
		titles = getTitles($content, isPreview && config.useDisambig);
	}
	getTaggedPages(titles, function (classNames) {
		getLinks($content).each(function () {
			markLink(this, classNames);
		});
	});
}

function init () {
	if (
		(
			config.onlyCheckMainNS &&
			mw.config.get('wgContentNamespaces').indexOf(mw.config.get('wgNamespaceNumber')) === -1
		) || (
			config.dontCheckSpecial && mw.config.get('wgNamespaceNumber') === -1
		) || (
			config.onlyCheckCurrent && mw.config.get('wgCurRevisionId') !== mw.config.get('wgRevisionId')
		)
	) {
		return;
	}
	mw.util.addCSS(config.css);
	mw.hook('wikipage.content').add(run);
}

$.extend(config, getConfig(mw.config.get('wgDBname')));
mw.hook('userjs.load-script.bklCheck').fire(config);

if (['view', 'edit', 'submit'].indexOf(mw.config.get('wgAction')) > -1 && !$.isEmptyObject(config.cats)) {
	mw.loader.using('mediawiki.util').then(init);
}

})(jQuery, mediaWiki);
//</nowiki>