MediaWiki:Gadget-green links.js

Definition från Wiktionary, den fria ordlistan.
Hoppa till navigering Hoppa till sök

OBS: Efter du har publicerat sidan kan du behöva tömma din webbläsares cache för att se ändringarna.

  • Firefox / Safari: Håll ned Skift och klicka på Uppdatera sidan eller tryck Ctrl-F5 eller Ctrl-R (⌘-R på Mac)
  • Google Chrome: Tryck Ctrl-Skift-R (⌘-Skift-R på Mac)
  • Internet Explorer / Edge: Håll ned Ctrl och klicka på Uppdatera eller tryck Ctrl-F5
  • Opera: Tryck Ctrl-F5.
/**
 * Gröna länkar
 *
 * Visa gröna länkar för att enkelt kunna skapa nya uppslag utifrån böjningsformer och översättningar.
 * Används också i [[MediaWiki:Gadget-translation editor.js]].
 */

/*global mw, $ */

var h3sByCode = {
	subst: 'Substantiv',
	verb: 'Verb',
	adj: 'Adjektiv',
	adv: 'Adverb',
	räkn: 'Räkneord',
	prep: 'Preposition',
	konj: 'Konjunktion',
	interj: 'Interjektion',
	pron: 'Pronomen',
	artikel: 'Artikel',
	verbpartikel: 'Verbpartikel',
	talesätt: 'Talesätt',
	ordspråk: 'Ordspråk',
	förkortning: 'Förkortning',
	affix: 'Affix',
	förled: 'Förled',
	efterled: 'Efterled',
	fras: 'Fras',
};
// Flip
var h3sByName = {};
for (var code in h3sByCode) {
	h3sByName[h3sByCode[code]] = code;
}

mw.util.addCSS('a.new.green-link { color: #2c0 }');

function getTemplateInfo(link) {
	var template = $(link).closest('.grammar, .grammar-inline');
	var data = template.data();

	if (data && data.lang && data.h3) {
		return data;
	}

	var match = /\btemplate\-([a-zåäö]+)\-([a-zåäö]+)/.exec(
		template.attr('class') || ''
	);

	if (match) {
		return {
			lang: match[1],
			h3: match[2],
		};
	}
}

function getH3(parent, link) {
	// The parent node may be detached, and it may or may not contain the related H3s.
	// Solution: Use all H3s in the document, and also all H3s of the parent.
	var name = $('h3').add($(parent).find('h3'))
		.filter(function() {
			return !!(this.compareDocumentPosition(link) & 4);
		})
		.last()
		.find('.mw-headline')
		.text();

	return {
		name: name,
		code: h3sByName[name],
	};
}

var linkPropsByUrl = {};

function camelToSnake(str) {
	return str.replace(/[A-ZÅÄÖ]/g, '_$&').toLowerCase();
}

function stringifySnakily(obj) {
	return JSON.stringify(obj).replace(/"([a-zåäö0-9]+[A-ZÅÄÖ][^"\\]*)":/g, function(
		match,
		key
	) {
		return '"' + camelToSnake(key) + '":';
	});
}

function getUnique(array, mapFn) {
	array = array.map(mapFn);

	var obj = {};
	for (var i = 0; i < array.length; i++) {
		obj[array[i]] = true;
	}

	array = [];
	for (var key in obj) {
		array.push(key);
	}

	return array;
}

function updateUrl(e) {
	var allProps = linkPropsByUrl[this.href];

	if (!allProps) {
		return;
	}

	var summary = getUnique(allProps, function(props) {
		return props.summary;
	}).join('; ');

	var target = mw.util.getParamValue('title', this.href);

	// Format definierat av [[MediaWiki:Gadget-editorwarnings.js]]
	var warnings = [];

	var data = {
		origin_pagename: mw.config.get('wgTitle'),
		entries: allProps.map(function(props) {
			// Parameter text= i {{ö}} ger data-custom-link-text
			if (props.entry.customLinkText && props.entry.customLinkText !== target) {
				warnings.push({
					type: 'confirm',
					introHtml:
						'Sidan du håller på att skapa är <b>' +
						mw.html.escape(target) +
						'</b>, men texten på länken du klickade på var <b>' +
						mw.html.escape(props.entry.customLinkText) +
						'</b>. Länktexten och länken brukar skilja sig åt när något rörande översättningen avviker från det vanliga.' +
						' Det är troligt att utformningen av den här sidan behöver anpassas innan den sparas.',
					checkboxLabel:
						'Jag känner till speciella strukturprinciper och är extra uppmärksam på att allt blir rätt.',
				});
			}

			return $.extend(
				{ title: $(props.link).text() },
				// Om `title` ges i props.entry, så använder vi den titeln (ges t.ex. via {{ö}})
				props.entry
			);
		}),
	};

	var json = stringifySnakily(data);
	var text = '{' + '{subst:#invoke:entry|getWikitext| ' + json + ' }}';

	this.href +=
		'&summary=' +
		encodeURIComponent(summary) +
		'#preloadtext=' +
		encodeURIComponent(text) +
		(warnings.length
			? '&preloadwarnings=' + encodeURIComponent(JSON.stringify(warnings))
			: '');
}

function updateLink(props) {
	var url = props.link.href;
	if (url.indexOf('?') !== -1) {
		if (!linkPropsByUrl[url]) {
			linkPropsByUrl[url] = [];
		}
		linkPropsByUrl[url].push(props);

		$(props.link)
			.on('click mouseover mousedown', updateUrl)
			.addClass('green-link');
	}
}

function addGreenLinks(parent) {
	var title = mw.config.get('wgTitle');
	var namespace = mw.config.get('wgNamespaceNumber');

	if (
		!parent &&
		(namespace !== 0 && namespace !== 2) &&
		title !== 'Wiktionary:Sandlådan'
	) {
		return;
	}
	if (!parent) {
		parent = $('#bodyContent');
	}

	// Inga gröna länkar till böjningar på flerordsuppslag
	if (title.indexOf(' ') === -1) {
		parent
			.find(
				'[data-grammar-link]>a.new, span.b->a.new, span.adv->a.new, span.prespart->a.new, span.perfpart->a.new, span.aktpart->a.new, span.passpart->a.new'
			)
			.each(function() {
				var span = $(this).parent();
				var template = getTemplateInfo(this);

				if (!template) {
					return;
				}

				var type = span.data('grammar-link') || span.attr('class');

				if (type === 'infl' || type === 'b-') {
					// Böjningsformer
					updateLink({
						link: this,
						summary: 'böjningsform av [[' + title + ']]',
						entry: {
							type: 'infl',
							lang: template.lang,
							h3: template.h3,
						},
					});
				} else if (type === 'adv' || type === 'adv-') {
					// Adverb
					updateLink({
						link: this,
						summary: 'avledning till [[' + title + ']]',
						entry: {
							type: 'adv',
							lang: template.lang,
							h3: 'adv',
							origin_h3: template.h3,
						},
					});
				} else if (type === 'prespart' || type === 'prespart-') {
					// Presensparticip
					updateLink({
						link: this,
						summary: 'presensparticip av [[' + title + ']]',
						entry: {
							type: 'prespart',
							lang: template.lang,
							h3: 'adj',
						},
					});
				} else if (type === 'perfpart' || type === 'perfpart-') {
					// Perfektparticip
					updateLink({
						link: this,
						summary: 'perfektparticip av [[' + title + ']]',
						entry: {
							type: 'perfpart',
							lang: template.lang,
							h3: 'adj',
						},
					});
				} else if (type === 'aktpart' || type === 'aktpart-') {
					// Aktiv particip
					updateLink({
						link: this,
						summary: 'aktiv particip av [[' + title + ']]',
						entry: {
							type: 'aktpart',
							lang: template.lang,
							h3: 'adj',
						},
					});
				} else if (type === 'passpart' || type === 'passpart-') {
					// Passiv particip
					updateLink({
						link: this,
						summary: 'passiv particip av [[' + title + ']]',
						entry: {
							type: 'passpart',
							lang: template.lang,
							h3: 'adj',
						},
					});
				} else {
					// Allt annat
					updateLink({
						link: this,
						summary: 'avledning till [[' + title + ']]',
						entry: {
							type: type,
							lang: template.lang,
							origin_h3: template.h3,
						}
					})
				}
			});
	}

	// Översättningar
	parent.find('span.ö>a.new').each(function() {
		// The parent span has attributes such as data-lang, data-gender-number, data-tr
		var entry = $(this)
			.parent()
			.data();
		entry.type = 'translation';
		entry.h3 = getH3(parent, this).code;

		updateLink({
			link: this,
			summary: 'översättning av [[' + title + ']]',
			entry: entry,
		});
	});
}
mw.hook('wikipage.content').add(addGreenLinks);

// Exportera funktionen addGreenLinks(), för den används i [[MediaWiki:Gadget-translation editor.js]]
window.addGreenLinks = addGreenLinks;