MediaWiki:Gadget-zglos-do-wyroznienia.js

Z Wikipedii, wolnej encyklopedii

Uwaga: aby zobaczyć zmiany po opublikowaniu, może zajść potrzeba wyczyszczenia pamięci podręcznej przeglądarki.

  • Firefox / Safari: Przytrzymaj Shift podczas klikania Odśwież bieżącą stronę, lub naciśnij klawisze Ctrl+F5, lub Ctrl+R (⌘-R na komputerze Mac)
  • Google Chrome: Naciśnij Ctrl-Shift-R (⌘-Shift-R na komputerze Mac)
  • Internet Explorer / Edge: Przytrzymaj Ctrl, jednocześnie klikając Odśwież, lub naciśnij klawisze Ctrl+F5
  • Opera: Naciśnij klawisze Ctrl+F5.
//@ts-check
/**
 * @author [[w:pl:User:Msz2001]]
 * 
 * A gadget that simplifies the nomination for featuring an article.
 * 
 * All nomination types should be added to the `zdw.nominationTypes` array.
 * Exposes an API object as `zdw.api`.
 * <nowiki>
 */
(function ($, mw) {
	var MSG = {
		dialogTitle: 'Zgłoś do wyróżnienia',
		dialogCancel: 'Anuluj',
		dialogConfirm: 'Zatwierdź',
		toolboxLink: 'Zgłoś do wyróżnienia',
		toolboxLinkTooltip: 'Zgłoś ten artykuł do wyróżnienia lub weryfikacji wyróżnienia w ramach projektu Wyróżniona Zawartość Wikipedii',

		nominationTypeLabel: 'Rodzaj zgłoszenia',
		errorFormInvalid: 'Formularz nie został wypełniony poprawnie: <ul>$1</ul>',
		noNominationTypes: 'Ten artykuł aktualnie nie może zostać zgłoszony do żadnego wyróżnienia.'
	};

	// Only those who made at least this many edits will be able to use the gadget.
	// Applies to all namespaces.
	var EDIT_COUNT_TRESHOLD = 100;
	// Default nomination type
	var DEFAULT_INDEX = 0;

	var nominationDialog;
	var errorContainer;

	var currentNominationType;

	/**
	 * Installs the gadget.
	 */
	function install() {
		var ns = mw.config.get('wgNamespaceNumber');
		if(ns !== 0) return;

		var editCount = mw.config.get('wgUserEditCount');
		if(editCount < EDIT_COUNT_TRESHOLD) return;

		window.zdw = window.zdw || { nominationTypes: [] };

		var portletId = mw.config.get('skin') === 'timeless' ? 'p-pagemisc' : 'p-tb';
		var link = mw.util.addPortletLink(portletId, 'javascript:void(0)', MSG.toolboxLink, 't-wzw', MSG.toolboxLinkTooltip);

		$(link).on('click', function () {
			zdw.nominationTypes = zdw.nominationTypes.sort(function (a, b) {
				return a.sortOrder - b.sortOrder;
			});

			if(!filterNominationTypes()) return;
			initializeDialog().then(function (dialog) {
				dialog.open();
			}).fail(function () {
				alert('Nie udało się załadować biblioteki OOUI. Spróbuj odświeżyć stronę');
			});
		});
	}

	/**
	 * Loads dependencies and creates a dialog
	 * @returns {JQuery.Promise<OO.ui.ProcessDialog>}
	 */
	function initializeDialog() {
		var deferred = $.Deferred();

		mw.loader.using(
			['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows', 'mediawiki.api', 'mediawiki.Title', 'mediawiki.messagePoster'],
			function () {
				initializeApi();
				nominationDialog = nominationDialog || new (createDialogClass())({ size: 'large' });

				deferred.resolve(nominationDialog);
			},
			deferred.reject
		);

		return deferred.promise();
	}

	/**
	 * Initializes the MediaWiki API and exposes it as a global object
	 */
	function initializeApi(){
		window.zdw = window.zdw || {};
		zdw.api = new mw.Api({
			parameters: {
				format: 'json',
				formatversion: 2,
				errorformat: 'html',
				errorlang: mw.config.get('wgUserLanguage'),
				errorsuselocal: true
			}
		});
	}

	/**
	 * Filters the nomination types to keep only those that are valid for the current article.
	 * @returns {boolean} Whether there are any valid nomination types.
	 */
	function filterNominationTypes(){
		var categories = mw.config.get('wgCategories');

		zdw.nominationTypes = zdw.nominationTypes.filter(function (nominationType) {
			if(typeof nominationType.isApplicable !== 'function') return true;
			return nominationType.isApplicable(categories);
		});

		if(!zdw.nominationTypes || zdw.nominationTypes.length == 0) {
			alert(MSG.noNominationTypes);
			return false;
		}

		if(zdw.nominationTypes.length >= DEFAULT_INDEX) {
			currentNominationType = zdw.nominationTypes[DEFAULT_INDEX];
		} else {
			currentNominationType = zdw.nominationTypes[0];
		}
		return true;
	}

	/**
	 * Create a class that's used to create the dialog
	 * @returns {OO.ui.ProcessDialog.class}
	 */
	function createDialogClass() {
		var windowManager = new OO.ui.WindowManager();
		$(document.body).append(windowManager.$element);

		function NominationDialog(config) {
			NominationDialog.super.call(this, config);
			windowManager.addWindows([this]);
		}
		OO.inheritClass(NominationDialog, OO.ui.ProcessDialog);

		NominationDialog.static.name = 'featureNominationDialog';
		NominationDialog.static.title = MSG.dialogTitle;
		NominationDialog.static.actions = [
			{
				action: 'confirm',
				label: MSG.dialogConfirm,
				flags: ['primary', 'progressive']
			},
			{
				label: MSG.dialogCancel,
				flags: 'safe'
			}
		];

		NominationDialog.prototype.initialize = function () {
			NominationDialog.super.prototype.initialize.apply(this, arguments);

			this.$body.append(createDialogView().$element);
		};

		NominationDialog.prototype.getActionProcess = function (action) {
			var dialog = this;
			if(action === 'confirm') {
				if(typeof currentNominationType.submit === 'function') {
					var validity = currentNominationType.validateForm();

					if(!validity.isValid) {
						var errorsList = validity.messages.map(function (x) { return '<li>' + x + '</li>'; });
						errorContainer.html(
							MSG.errorFormInvalid.replace(/\$1/g, errorsList.join(''))
						).show();
						return new OO.ui.Process(function () { });
					} else {
						errorContainer.html('').hide();
					}

					return currentNominationType.submit(currentNominationType)
						.next(function () {
							dialog.close({
								action: action
							});
							location.reload();
						});
				}
			}
			// Fallback to parent handler.
			return NominationDialog.super.prototype.getActionProcess.call(this, action);
		};

		return NominationDialog;
	}

	/**
	 * Prepares controls to be displayed in the dialog
	 * @returns {OO.ui.PanelLayout}
	 */
	function createDialogView() {
		var rootPanel = new OO.ui.PanelLayout({
			padded: true,
			expanded: false,
		});

		// Here will be displayed any errors
		errorContainer = $('<div class="mw-gadget-zdw-errorbox"></div>').hide();
		rootPanel.$element.append(errorContainer);

		var fieldset = new OO.ui.FieldsetLayout({});
		rootPanel.$element.append(fieldset.$element);

		// The "Nomination type" field
		var typeOptions = zdw.nominationTypes.map(
			function (t, i) { return { data: i, label: $('<span><span style="display:inline-block; width:16px; height:18px; text-align:center; margin-right:1ex;"><img src="' + t.icon + '" /></span>' + t.label + '</span>') }; }
		);
		var typeInput = new OO.ui.DropdownInputWidget({
			options: typeOptions,
			value: DEFAULT_INDEX
		});
		var typeField = new OO.ui.FieldLayout(typeInput, {
			label: MSG.nominationTypeLabel,
			align: 'left'
		});

		// The stack of panels for various nomination types
		var panels = [];
		for(var i = 0; i < zdw.nominationTypes.length; i++) {
			var type = zdw.nominationTypes[i];

			if(!type.view) type.view = type.createView();
			var view = type.view;

			if(panels.indexOf(view) > -1) continue;
			panels.push(view);
		}

		var detailsStack = new OO.ui.StackLayout({
			expanded: false,
			items: panels
		});
		detailsStack.setItem(currentNominationType.view);

		fieldset.addItems([typeField]);

		rootPanel.$element.append(fieldset.$element);
		rootPanel.$element.append(detailsStack.$element);

		typeInput.on('change', function (value) {
			currentNominationType = zdw.nominationTypes[value];
			detailsStack.setItem(currentNominationType.view);
			nominationDialog.updateSize();
		});

		return rootPanel;
	}

	install();
})($, mw);
// </nowiki>