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
  • Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
//Dokumentation unter [[Benutzer:Schnark/js/veSummary]] <nowiki>
//see [[phab:T50274]]
/*global mediaWiki, OO, ve*/
/*jshint evil: true, unused: false*/
(function ($, mw) {
"use strict";

mw.hook('ve.activationComplete').add(function () {
//virtual indent
mw.loader.using(['mediawiki.util', 'mediawiki.api', 'ext.visualEditor.articleTarget']).then(function (require) {

	var cachedRequest;

	function getDefaultSummaryList (wiki) {
		/*jshint onecase: true*/
		switch (wiki) {
		case 'dewiki':
			return [
				'Rechtschreibung korrigiert',
				'Grammatik korrigiert',
				'ergänzt',
				'aktualisiert',
				'überarbeitet',
				'formatiert',
				'Link korrigiert',
				'siehe Diskussion',
				'korrigiert',
				'Typografie'
			];
		default:
			return [];
		}
	}

	function getSortedSummaries (summaries) {
		return Object.keys(summaries).sort(function (a, b) {
			return summaries[b].c - summaries[a].c;
		});
	}

	function requestContribs () {
		return (new mw.Api()).get({
			list: 'usercontribs',
			ucuser: mw.config.get('wgUserName'),
			ucprop: 'comment|title',
			uclimit: 500,
			formatversion: 2
		}).then(function (json) {
			if (!json || !json.query) {
				return [];
			}
			return json.query.usercontribs || [];
		}, function () {
			return [];
		});
	}

	function requestAllSummariesFromApi () {
		return requestContribs().then(function (contribs) {
			var summaries = {};
			contribs.forEach(function (contrib) {
				var summary = (contrib.comment || '').replace(/^\/\*.*?\*\/\s*/, '').trim();
				if (!summary || summary.indexOf('/*') > -1) {
					return;
				}
				if (!summaries[summary]) {
					summaries[summary] = {c: 0};
				}
				summaries[summary].c += (contrib.ns === mw.config.get('wgNamespaceNumber') ? 2 : 1);
			});
			getDefaultSummaryList(mw.config.get('wgDBname')).forEach(function (summary) {
				if (!summaries[summary]) {
					summaries[summary] = {c: 0};
				}
				summaries[summary].c += 1;
			});
			return getSortedSummaries(summaries);
		});
	}

	function requestAllSummaries () {
		if (!cachedRequest) {
			cachedRequest = requestAllSummariesFromApi();
		}
		return cachedRequest;
	}

	function getMatchingSummaries (all, origInput) {
		var s1 = [], s2 = [], s3 = [],
			input = origInput.toLowerCase();
		all.forEach(function (summary) {
			var pos = summary.toLowerCase().indexOf(input);
			if (pos === 0) {
				if (origInput !== summary) {
					s1.push(summary);
				}
			} else if (pos > -1) {
				if (summary.toLowerCase().indexOf(' ' + input) > -1) {
					s2.push(summary);
				} else {
					s3.push(summary);
				}
			}
		});
		s1 = s1.concat(s2, s3);
		return s1;
	}

	//split a summary into the section and the actual summary
	function splitSummary (summary) {
		var result = /^(\/\*.*?\*\/\s*)?(.*)$/.exec(summary);
		return [result[1] || '', result[2]];
	}

	//get the label for the summary (i.e. truncate nicely when it is too long)
	function getLabel (summary) {
		if (summary.length <= 60) {
			return summary;
		}
		summary = splitSummary(summary);
		if (summary[0]) {
			summary[0] = '/*…*/ ';
		}
		summary = summary[0] + summary[1];
		return summary;
	}

	//widget for edit summaries
	function EditSummaryWidget (config) {
		EditSummaryWidget.parent.call(this, config);
		OO.ui.mixin.LookupElement.call(this, config);
		this.limit = config.limit || 10;
	}
	OO.inheritClass(EditSummaryWidget, OO.ui.MultilineTextInputWidget);
	OO.mixinClass(EditSummaryWidget, OO.ui.mixin.LookupElement);

	EditSummaryWidget.prototype.getLookupRequest = function () {
		var input = splitSummary(this.value), limit = this.limit;
		return requestAllSummaries().then(function (allSummaries) {
			var section = input[0],
				s = getMatchingSummaries(allSummaries, input[1]);
			if (s.length > limit) {
				s.length = limit;
			}
			if (section) {
				s = s.map(function (summary) {
					return section + summary;
				});
			}
			return s;
		}).promise({abort: $.noop}); //don't abort, the actual request will be the same anyway
	};

	EditSummaryWidget.prototype.getLookupCacheDataFromResponse = function (r) {
		return r;
	};

	EditSummaryWidget.prototype.getLookupMenuOptionsFromData = function (data) {
		var i, items = [];
		for (i = 0; i < data.length; i++) {
			items.push(new OO.ui.MenuOptionWidget({label: getLabel(data[i]), data: data[i]}));
		}
		return items;
	};

	//do not show suggestions just on focus; yes, the method is marked as protected, but who cares ([[phab:T169484]])
	EditSummaryWidget.prototype.onLookupInputFocus = function () {
		this.lookupInputFocused = true;
	};

	EditSummaryWidget.prototype.focus = function () { //HACK ([[phab:T196117]])
		EditSummaryWidget.parent.prototype.focus.apply(this, arguments);
		this.lookupMenu.width = this.$input[0].clientWidth + 2;
	};

	//hack around MWSaveDialog to use our EditSummaryWidget
	ve.ui.MWSaveDialog.prototype.initialize = eval('(' +
		ve.ui.MWSaveDialog.prototype.initialize.toString().replace(
			/OO\s*\.\s*ui\s*\.\s*MultilineTextInputWidget\s*\(\s*\{/,
			'EditSummaryWidget({' +
				'allowSuggestionsWhenEmpty: true,' +
				//since the suggestions don't show when opening the dialog,
				//[[phab:T155976]] doesn't apply
				'$overlay: this.$overlay,'
		) +
	')');
});
//virtual outdent
});

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