Hoppa till innehållet

MediaWiki:Gadget-RecentChangesStream.js

Från Wikipedia

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.
if ( mw.config.get( 'wgPageName' ) === 'Wikipedia:Senaste_ändringar/Flöde' && mw.config.get( 'wgAction' ) === 'view' ) {
	$( function() {
		'use strict';
		var api = new mw.Api();
		var separator = '<span class="gadget-recentchangesstream-separator"> .. </span>';
		var diff = 'diff';
		var esc = mw.html.escape;
		var text = 'Settings';
		var tooltip = 'Settings for the RecentChanges stream';
		var link;
		var propdesc = 'Choose which properties you want to fetch and view';
		var limitdesc = 'Choose how many actions you want to fetch and view';
		var typedesc = 'Choose which type of actions you want to fetch and view';
		var timedesc = 'Set the time interval (in number of milliseconds) between the updates';
		var namespacedesc = 'Select which namespaces you want to view';
		var propidslabel = 'Diff link';
		var proptitlelabel = 'Page title';
		var proptimestamplabel = 'Time stamp';
		var propuserlabel = 'User';
		var propparsedcommentlabel = 'Edit comment';
		var proptagslabel = 'Tags';
		var proploginfolabel = 'Log info';
		var typeeditlabel = 'Edits';
		var typenew = 'New page';
		var typenewlabel = 'New pages';
		var typeloglabel = 'Log actions';
		var typecategorizelabel = 'Categorizations';
		var namespace0label = 'Article';
		var namespace1label = 'Talk';
		var namespace2label = 'User';
		var namespace3label = 'User talk';
		var namespace4label = 'Wikipedia';
		var namespace5label = 'Wikipedia talk';
		var namespace8label = 'MediaWiki';
		var namespace9label = 'MediaWiki talk';
		var namespace10label = 'Template';
		var namespace11label = 'Template talk';
		var namespace14label = 'Category';
		var namespace15label = 'Category talk';
		var namespace100label = 'Portal';
		var namespace101label = 'Portal talk';
		var namespace828label = 'Module';
		var namespace829label = 'Module talk';
		var toponlylabel = 'Only show the latest edit per page';
		var excludeuserslabel = 'Exclude users (separate with newline)';
		var soundfilelabel = 'Sound file to play when a new edit with a tag pops up (leave empty to not play any sound)';
		var closelabel = 'Close';
		var propkey = 'gadget-recentchangesstream-props';
		var typekey = 'gadget-recentchangesstream-types';
		var showkey = 'gadget-recentchangesstream-show';
		var limitkey = 'gadget-recentchangesstream-limit';
		var namespacekey = 'gadget-recentchangesstream-namespace';
		var toponlykey = 'gadget-recentchangesstream-toponly';
		var excludeduserskey = 'gadget-recentchangesstream-excludedusers';
		var soundfilekey = 'gadget-recentchangesstream-soundfile';
		var timekey = 'gadget-recentchangesstream-time';
		var logtypemove = 'moved';
		var from = ' from ';
		var to = ' to ';
		var logactionmoveredir = ' over a redirect';
		var logtypemovesuppressredirect = ' without leaving a redirect';
		var logactiondelete = 'deleted';
		var logactionrestore = 'restored';
		var logactiondeleteredir = 'deleted redirect';
		var logactioncreate = 'New user';
		var logactioncreate2 = 'created account';
		var logactionbyemail = 'password was sent by email';
		var logactionblock = 'blocked';
		var logactionreblock = 'changed block settings for';
		var logactionunblock = 'unblocked';
		var logactionprotect = 'protected';
		var logactionmodify = 'changed protection settings for';
		var logactionunprotect = 'unprotected';
		var logactionrenameuser = 'renamed';
		var logactionchange = 'changed content model for';
		var logactionrights = 'changed user groups for';
		var logactionrevision = 'changed visibility for';
		var logactionevent = 'changed visibility for log action';
		var logtypeabusefilter = 'changed filter';
		function getProps() {
			if ( localStorage.getItem( propkey ) ) {
				return localStorage.getItem( propkey ).split( ',' );
			} else {
				return [
					'title',
					'ids',
					'user',
					'parsedcomment',
					'tags',
					'loginfo'
				];
			}
		}
		function getTypes() {
			if ( localStorage.getItem( typekey ) ) {
				return localStorage.getItem( typekey ).split( ',' );
			} else {
				return [
					'edit',
					'new',
					'log'
				];
			}
		}
		function getShow() {
			if ( localStorage.getItem( showkey ) ) {
				return localStorage.getItem( showkey ).split( ',' );
			} else {
				return '!bot';
			}
		}
		function getLimit() {
			if ( localStorage.getItem( limitkey ) ) {
				return localStorage.getItem( limitkey );
			} else {
				return 10;
			}
		}
		function getNamespaces() {
			if ( localStorage.getItem( namespacekey ) ) {
				return localStorage.getItem( namespacekey ).split( ',' );
			} else {
				return [];
			}
		}
		function getToponly() {
			if ( localStorage.getItem( toponlykey ) ) {
				return localStorage.getItem( toponlykey );
			}
		}
		function getExcludedUsers() {
			var excludedusersoutput = mw.storage.get( excludeduserskey );
			if ( excludedusersoutput ) {
				excludedusersoutput = excludedusersoutput.trim();
				if ( excludedusersoutput ) {
					return excludedusersoutput.split( '\n' );
				}
			}
			return [];
		}
		var oldrcids = [];
		var tagswhitelist = [
			'avsnittsblankning',
			'testredigering',
			'klotter',
			'Enbart versaler',
			'onormalt många blanktecken',
			'kort ny artikel',
			'artikelnamnet inte inkluderat',
			'startmallar kvarglömda',
			'lagt till epostadress',
			'IK-spam',
			'ovanliga tecken',
			'smileys',
			'tre eller fler skiljetecken',
			'signatur tillagd',
			'kontrollera redigeringen',
			'borttagning av raderamall',
			'upprepade tecken',
			'redigering av program',
			'onormalt många konsonanter',
			'mönsterbaserat upprepningsfilter',
			'felaktig omdirigering',
			'borttagning av alla kategorier',
			'text efter kategorier',
			'borttagning av tagg för referenslista',
			'owikifierad ny artikel',
			'onormalt långt ord',
			'text efter rubrik',
			'text efter tagg för referenslista',
			'text efter mall',
			'felaktig årtalslänk',
			'text före mall',
			'felaktig tagg för referenslista'
		];
		function getSoundFile() {
			var soundFile = localStorage.getItem( soundfilekey );
			if ( soundFile !== null ) {
				soundFile = soundFile.trim();
				if ( soundFile === '' ) {
					return null;
				} else {
					return soundFile;
				}
			} else {
				return 'https://upload.wikimedia.org/wikipedia/commons/3/37/Music_box_notes_6.ogg';
			}
		}
		function getActions() {
			var obj = {
				action: 'query',
				list: 'recentchanges',
				rcprop: getProps(),
				rctype: getTypes(),
				rcshow: getShow(),
				rclimit: getLimit()
			};
			if ( ( getNamespaces() ).length ) {
				obj.rcnamespace = getNamespaces();
			}
			if ( getToponly() ) {
				obj.rctoponly = true;
			}
			if ( ( getExcludedUsers() ).length === 1 ) {
				obj.rcexcludeuser = ( getExcludedUsers() )[ 0 ];
			}
			api.get( obj ).done( function( data ) {
				var str = '';
				var changes = data.query.recentchanges;
				var newrcids = changes.map( function( curr ) {
					return curr.rcid;
				} );
				var diffrcids = newrcids.filter( function( v ) {
					return !oldrcids.includes( v );
				} );
				var newtags;
				oldrcids = newrcids;
				if ( diffrcids.length ) {
					changes.some( function( change ) {
						if ( diffrcids.includes( change.rcid ) ) {
							if ( change.tags ) {
								if ( change.tags.length ) {
									newtags = change.tags.filter( function( tag ) {
										return tagswhitelist.includes( tag );
									} );
								}
							}
						}
					} );
					if ( newtags ) {
						if ( newtags.length ) {
							if ( getSoundFile() ) {
								( new Audio( getSoundFile() ) ).play();
							}
						}
					}
				}
				changes.forEach( function( curr ) {
					if ( curr.type === 'edit' ) {
						str += '<li class="gadget-recentchangesstream-list-edit">';
						if ( curr.revid ) {
							str += '<a href="/wiki/Special:Diff/' + curr.revid + '" class="gadget-recentchangesstream-revid">' + diff + '</a>';
						}
						if ( curr.title ) {
							str += separator + '<a href="/wiki/' + esc( curr.title ) + '" class="gadget-recentchangesstream-title">' + curr.title + '</a>';
						}
						if ( curr.timestamp ) {
							str += separator + '<span class="gadget-recentchangesstream-timestamp">' + curr.timestamp + '</span>';
						}
						if ( curr.user ) {
							str += separator + '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
						}
						if ( curr.parsedcomment ) {
							str += separator + '<span class="gadget-recentchangesstream-parsedcomment">' + curr.parsedcomment + '</span>';
						}
						if ( curr.tags ) {
							if ( curr.tags.length ) {
								str += separator + '<span class="gadget-recentchangesstream-tags">' + curr.tags.join( ', ' ) + '</span>';
							}
						}
						str = str + '</li>';
					} else if ( curr.type === 'new' ) {
						str += '<li class="gadget-recentchangesstream-list-new">' + typenew;
						if ( curr.title ) {
							str += separator + '<a href="/wiki/' + esc( curr.title ) + '" class="gadget-recentchangesstream-title">' + curr.title + '</a>';
						}
						if ( curr.timestamp ) {
							str += separator + '<span class="gadget-recentchangesstream-timestamp">' + curr.timestamp + '</span>';
						}
						if ( curr.user ) {
							str += separator + '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
						}
						if ( curr.parsedcomment ) {
							str += separator + '<span class="gadget-recentchangesstream-parsedcomment">' + curr.parsedcomment + '</span>';
						}
						if ( curr.tags ) {
							if ( curr.tags.length ) {
								str += separator + '<span class="gadget-recentchangesstream-tags">' + curr.tags.join( ', ' ) + '</span>';
							}
						}
						str += '</li>';
					} else if ( curr.type === 'log' ) {
						str += '<li class="gadget-recentchangesstream-list-log">';
						if ( curr.logtype === 'move' ) {
							if ( curr.user ) {
								str += '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
							}
							str += separator + logtypemove;
							if ( curr.title ) {
								str += separator + '<a href="/wiki/' + esc( curr.title ) + '" class="gadget-recentchangesstream-title">' + curr.title + '</a>';
								if ( curr.logparams ) {
									if ( curr.logparams.target_title ) {
										str += to + '<a href="/wiki/' + esc( curr.logparams.target_title ) + '">' + curr.logparams.target_title + '</a>';
									}
									if ( curr.logaction === 'move_redir' ) {
										str += logactionmoveredir;
									}
									if ( curr.logparams.hasOwnProperty( 'suppressredirect' ) ) {
										str += logtypemovesuppressredirect;
									}
								}
							}
						} else if ( curr.logtype === 'delete' ) {
							if ( curr.user ) {
								str += '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
							}
							if ( curr.logaction === 'delete' ) {
								str += separator + logactiondelete;
							} else if ( curr.logaction === 'restore' ) {
								str += separator + logactionrestore;
							} else if ( curr.logaction === 'delete_redir' ) {
								str += separator + logactiondeleteredir;
							} else if ( curr.logaction === 'revision' ) {
								str += separator + logactionrevision;
							} else if ( curr.logaction === 'event' ) {
								str += separator + logactionevent;
							}
							if ( curr.title ) {
								str += separator + '<a href="/wiki/' + esc( curr.title ) + '" class="gadget-recentchangesstream-title">' + curr.title + '</a>';
							}
						} else if ( curr.logtype === 'newusers' ) {
							if ( curr.logaction === 'create' ) {
								str += logactioncreate + separator;
								if ( curr.user ) {
									str += '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
								}
							} else if ( curr.logaction === 'create2' ) {
								if ( curr.user ) {
									str += '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
								}
								str += separator + logactioncreate2;
								if ( curr.title ) {
									str += separator + '<a href="/wiki/' + esc( curr.title ) + '" class="gadget-recentchangesstream-title">' + curr.title + '</a>';
								}
							} else if ( curr.logaction === 'byemail' ) {
								if ( curr.user ) {
									str += '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
								}
								str += separator + logactioncreate2;
								if ( curr.title ) {
									str += separator + '<a href="/wiki/' + esc( curr.title ) + '" class="gadget-recentchangesstream-title">' + curr.title + '</a>';
								}
								str += separator + logactionbyemail;
							}
						} else if ( curr.logtype === 'block' ) {
							if ( curr.user ) {
								str += '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
							}
							if ( curr.logaction === 'block' ) {
								str += separator + logactionblock;
							} else if ( curr.logaction === 'reblock' ) {
								str += separator + logactionreblock;
							} else if ( curr.logaction === 'unblock' ) {
								str += separator + logactionunblock;
							}
							if ( curr.title ) {
								str += separator + '<a href="/wiki/' + esc( curr.title ) + '" class="gadget-recentchangesstream-title">' + curr.title + '</a>';
							}
							if ( curr.logparams ) {
								if ( curr.logparams.duration ) {
									str += separator + curr.logparams.duration;
								}
							}
						} else if ( curr.logtype === 'protect' ) {
							if ( curr.user ) {
								str += '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
							}
							if ( curr.logaction === 'protect' ) {
								str += separator + logactionprotect;
							} else if ( curr.logaction === 'modify' ) {
								str += separator + logactionmodify;
							} else if ( curr.logaction === 'unprotect' ) {
								str += separator + logactionunprotect;
							}
							if ( curr.title ) {
								str += separator + '<a href="/wiki/' + esc( curr.title ) + '" class="gadget-recentchangesstream-title">' + curr.title + '</a>';
							}
						} else if ( curr.logtype === 'renameuser' ) {
							if ( curr.user ) {
								str += '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
							}
							if ( curr.logaction === 'renameuser' ) {
								if ( curr.logparams ) {
									if ( curr.logparams.olduser && curr.logparams.newuser ) {
										str += separator + logactionrenameuser + separator + '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.logparams.olduser ) + '">' + curr.logparams.olduser + '</a>' + to + '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.logparams.newuser ) + '">' + curr.logparams.newuser + '</a>';
									}
								}
							}
						} else if ( curr.logtype === 'contentmodel' ) {
							if ( curr.user ) {
								str += '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
							}
							if ( curr.logaction === 'change' ) {
								str += separator + logactionchange;
							}
							if ( curr.title ) {
								str += separator + '<a href="/wiki/' + esc( curr.title ) + '" class="gadget-recentchangesstream-title">' + curr.title + '</a>';
							}
							if ( curr.logparams ) {
								if ( curr.logparams.oldmodel && curr.logparams.newmodel ) {
									str += from + curr.logparams.oldmodel + to + curr.logparams.newmodel;
								}
							}
						} else if ( curr.logtype === 'rights' ) {
							if ( curr.user ) {
								str += '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
							}
							if ( curr.logaction === 'rights' ) {
								str += separator + logactionrights;
							}
							if ( curr.title ) {
								str += separator + '<a href="/wiki/' + esc( curr.title ) + '" class="gadget-recentchangesstream-title">' + curr.title + '</a>';
							}
						} else if ( curr.logtype === 'merge' ) {
							if ( curr.user ) {
								str += '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
							}
						} else if ( curr.logtype === 'abusefilter' ) {
							if ( curr.user ) {
								str += '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
							}
							if ( curr.logaction === 'modify' ) {
								str += separator + logtypeabusefilter;
							}
							if ( curr.title && curr.logparams && curr.logparams[ 1 ] ) {
								str += separator + '<a href="/wiki/' + esc( curr.title ) + '" class="gadget-recentchangesstream-title">' + curr.logparams[ 1 ] + '</a>';
							}
						}
						if ( curr.timestamp ) {
							str += separator + '<span class="gadget-recentchangesstream-timestamp">' + curr.timestamp + '</span>';
						}
						if ( curr.parsedcomment ) {
							str += separator + '<span class="gadget-recentchangesstream-parsedcomment">' + curr.parsedcomment + '</span>';
						}
						str += '</li>';
					} else if ( curr.type === 'categorize' ) {
						str += '<li class="gadget-recentchangesstream-list-categorize">';
						if ( curr.title ) {
							str += '<a href="/wiki/' + esc( curr.title ) + '" class="gadget-recentchangesstream-title">' + curr.title + '</a>';
						}
						if ( curr.user ) {
							str += separator + '<a href="/wiki/Anv%C3%A4ndare:' + esc( curr.user ) + '" class="gadget-recentchangesstream-user">' + curr.user + '</a>';
						}
						if ( curr.timestamp ) {
							str += separator + '<span class="gadget-recentchangesstream-timestamp">' + curr.timestamp + '</span>';
						}
						if ( curr.parsedcomment ) {
							str += separator + '<span class="gadget-recentchangesstream-parsedcomment">' + curr.parsedcomment + '</span>';
						}
						str += '</li>';
					}
				} );
				$( '#gadget-recentchangesstream-list' ).html( str );
				mw.hook( 'svwikigadgetrecentchangesstream' ).fire();
			} );
		}
		function getTimeInterval() {
			if ( mw.storage.get( timekey ) ) {
				return mw.storage.get( timekey );
			} else {
				return 10 * 1000;
			}
		}
		if ( mw.config.get( 'wgUserLanguage' ) === 'sv' ) {
			diff = 'skillnad';
			text = 'Inställningar';
			tooltip = 'Inställningar för flödet för senaste ändringarna';
			propdesc = 'Välj de egenskaper du vill hämta och visa';
			limitdesc = 'Välj hur många handlingar du vill hämta och visa';
			typedesc = 'Välj vilken typ av handlingar du vill hämta och visa';
			timedesc = 'Bestäm tidsintervallet (i antal millisekunder) mellan uppdateringarna';
			namespacedesc = 'Välj vilka namnrymder du vill visa';
			propidslabel = 'Difflänk';
			proptitlelabel = 'Sidtitel';
			proptimestamplabel = 'Tidsstämpel';
			propuserlabel = 'Användare';
			propparsedcommentlabel = 'Redigeringskommentar';
			proptagslabel = 'Märken';
			proploginfolabel = 'Logginfo';
			typeeditlabel = 'Redigeringar';
			typenew = 'Ny sida';
			typenewlabel = 'Nya sidor';
			typeloglabel = 'Logghandlingar';
			typecategorizelabel = 'Kategoriseringar';
			namespace0label = 'Artikel';
			namespace1label = 'Diskussion';
			namespace2label = 'Användare';
			namespace3label = 'Användardiskussion';
			namespace4label = 'Wikipedia';
			namespace5label = 'Wikipediadiskussion';
			namespace8label = 'MediaWiki';
			namespace9label = 'MediaWiki-diskussion';
			namespace10label = 'Mall';
			namespace11label = 'Malldiskussion';
			namespace14label = 'Kategori';
			namespace15label = 'Kategoridiskussion';
			namespace100label = 'Portal';
			namespace101label = 'Portaldiskussion';
			namespace828label = 'Modul';
			namespace829label = 'Moduldiskussion';
			toponlylabel = 'Visa enbart den senaste redigeringen per sida';
			excludeuserslabel = 'Exkludera användare (separera med radbrytning)';
			soundfilelabel = 'Ljudfil att spela upp när en ny redigering med ett märke dyker upp (lämna blank för att inte spela upp något ljud)';
			closelabel = 'Stäng';
			logtypemove = 'flyttade';
			from = ' från ';
			to = ' till ';
			logactionmoveredir = ' över en omdirigering';
			logtypemovesuppressredirect = ' utan att lämna en omdirigering';
			logactiondelete = 'raderade';
			logactionrestore = 'återställde';
			logactiondeleteredir = 'raderade omdirigeringen';
			logactioncreate = 'Ny användare';
			logactioncreate2 = 'skapade kontot';
			logactionbyemail = 'lösenordet skickades via e-post';
			logactionblock = 'blockerade';
			logactionreblock = 'ändrade blockeringsinställningar för';
			logactionunblock = 'avblockerade';
			logactionprotect = 'skyddade';
			logactionmodify = 'ändrade skyddsinställningar för';
			logactionunprotect = 'tog bort skydd från';
			logactionrenameuser = 'bytte namn på';
			logactionchange = 'ändrade innehållsmodell för';
			logactionrights = 'ändrade användargrupper för';
			logactionrevision = 'ändrade synlighet för';
			logactionevent = 'ändrade synlighet för logghändelse';
			logtypeabusefilter = 'ändrade filter';
		}
		link = mw.util.addPortletLink(
			'p-tb',
			'#',
			text,
			'gadget-recentchangesstream',
			tooltip
		);
		$( link ).find( 'a' ).click( function( e ) {
			e.preventDefault();
			var props = getProps();
			var limit = getLimit();
			var types = getTypes();
			var time = getTimeInterval();
			var namespaces = getNamespaces();
			var toponly = getToponly();
			var soundFile = getSoundFile();
			var settingsstr = '<div><p>' + propdesc + '</p><div><input type="checkbox" name="gadget-recentchangesstream-prop" value="ids" id="gadget-recentchangesstream-prop-ids"';
			if ( props.includes( 'ids' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-prop-ids">' + propidslabel + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-prop" value="title" id="gadget-recentchangesstream-prop-title"';
			if ( props.includes( 'title' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-prop-title">' + proptitlelabel + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-prop" value="timestamp" id="gadget-recentchangesstream-prop-timestamp"';
			if ( props.includes( 'timestamp' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-prop-timestamp">' + proptimestamplabel + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-prop" value="user" id="gadget-recentchangesstream-prop-user"';
			if ( props.includes( 'user' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-prop-user">' + propuserlabel + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-prop" value="parsedcomment" id="gadget-recentchangesstream-prop-parsedcomment"';
			if ( props.includes( 'parsedcomment' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-prop-parsedcomment">' + propparsedcommentlabel + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-prop" value="tags" id="gadget-recentchangesstream-prop-tags"';
			if ( props.includes( 'tags' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-prop-tags">' + proptagslabel + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-prop" value="loginfo" id="gadget-recentchangesstream-prop-loginfo"';
			if ( props.includes( 'loginfo' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-prop-loginfo">' + proploginfolabel + '</label></div>';
			settingsstr += '<p>' + limitdesc + '</p>';
			settingsstr += '<input type="number" id="gadget-recentchangesstream-limit" value="' + String( limit ) + '">';
			settingsstr += '<p>' + typedesc + '</p>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-type" value="edit" id="gadget-recentchangesstream-type-edit"';
			if ( types.includes( 'edit' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-type-edit">' + typeeditlabel + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-type" value="new" id="gadget-recentchangesstream-type-new"';
			if ( types.includes( 'new' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-type-new">' + typenewlabel + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-type" value="log" id="gadget-recentchangesstream-type-log"';
			if ( types.includes( 'log' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-type-log">' + typeloglabel + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-type" value="categorize" id="gadget-recentchangesstream-type-categorize"';
			if ( types.includes( 'categorize' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-type-categorize">' + typecategorizelabel + '</label></div>';
			settingsstr += '<p>' + timedesc + '</p>';
			settingsstr += '<input type="number" id="gadget-recentchangesstream-time" value="' + String( time ) + '">';
			settingsstr += '<p>' + namespacedesc + '</p>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="0" id="gadget-recentchangesstream-namespace-0"';
			if ( namespaces.includes( '0' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-0">' + namespace0label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="1" id="gadget-recentchangesstream-namespace-1"';
			if ( namespaces.includes( '1' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-1">' + namespace1label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="2" id="gadget-recentchangesstream-namespace-2"';
			if ( namespaces.includes( '2' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-2">' + namespace2label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="3" id="gadget-recentchangesstream-namespace-3"';
			if ( namespaces.includes( '3' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-3">' + namespace3label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="4" id="gadget-recentchangesstream-namespace-4"';
			if ( namespaces.includes( '4' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-4">' + namespace4label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="5" id="gadget-recentchangesstream-namespace-5"';
			if ( namespaces.includes( '5' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-5">' + namespace5label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="8" id="gadget-recentchangesstream-namespace-8"';
			if ( namespaces.includes( '8' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-8">' + namespace8label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="9" id="gadget-recentchangesstream-namespace-9"';
			if ( namespaces.includes( '9' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-9">' + namespace9label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="10" id="gadget-recentchangesstream-namespace-10"';
			if ( namespaces.includes( '10' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-10">' + namespace10label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="11" id="gadget-recentchangesstream-namespace-11"';
			if ( namespaces.includes( '11' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-11">' + namespace11label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="14" id="gadget-recentchangesstream-namespace-14"';
			if ( namespaces.includes( '14' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-14">' + namespace14label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="15" id="gadget-recentchangesstream-namespace-15"';
			if ( namespaces.includes( '15' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-15">' + namespace15label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="100" id="gadget-recentchangesstream-namespace-100"';
			if ( namespaces.includes( '100' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-100">' + namespace100label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="101" id="gadget-recentchangesstream-namespace-101"';
			if ( namespaces.includes( '101' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-101">' + namespace101label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="828" id="gadget-recentchangesstream-namespace-828"';
			if ( namespaces.includes( '828' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-828">' + namespace828label + '</label></div>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-namespace" value="829" id="gadget-recentchangesstream-namespace-829"';
			if ( namespaces.includes( '829' ) ) {
				settingsstr += ' checked';
			}
			settingsstr += '><label for="gadget-recentchangesstream-namespace-829">' + namespace829label + '</label></div>';
			settingsstr += '<p><label for="gadget-recentchangesstream-toponly">' + toponlylabel + '</label></p>';
			settingsstr += '<div><input type="checkbox" name="gadget-recentchangesstream-toponly" value="true" id="gadget-recentchangesstream-toponly"';
			if ( toponly ) {
				settingsstr += ' checked';
			}
			settingsstr += '></div>';
			settingsstr += '<p><label for="gadget-recentchangesstream-excludeusers">' + excludeuserslabel + '</label></p>';
			settingsstr += '<textarea id="gadget-recentchangesstream-excludeusers"></textarea>';
			settingsstr += '<p><label for="gadget-recentchangesstream-soundfile">' + soundfilelabel + '</label></p>';
			settingsstr += '<div><input id="gadget-recentchangesstream-soundfile" value="';
			if ( soundFile ) {
				settingsstr += soundFile;
			}
			settingsstr += '"></div>';
			settingsstr += '<button id="gadget-recentchangesstream-close">' + closelabel + '</button>';
			settingsstr += '</div>';

			// Creating and opening a simple dialog window.

			// Subclass Dialog class. Note that the OOjs inheritClass() method extends the parent constructor's prototype and static methods and properties to the child constructor.

			function MyDialog( config ) {
				MyDialog.super.call( this, config );
			}
			var myDialog;
			var windowManager;
			if ( $( '.oo-ui-window-active' ).length === 0 ) {
				OO.inheritClass( MyDialog, OO.ui.Dialog );

				// Specify a title statically (or, alternatively, with data passed to the opening() method).
				MyDialog.static.name = 'gadgetrecentchangesstreamdialog';
				MyDialog.static.title = 'Simple dialog';

				// Customize the initialize() function: This is where to add content to the dialog body and set up event handlers.
				MyDialog.prototype.initialize = function () {
					// Call the parent method
					MyDialog.super.prototype.initialize.call( this );
					// Create and append a layout and some content.
					this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );
					this.content.$element.append( settingsstr );
					this.$body.append( this.content.$element );
					$( '#gadget-recentchangesstream-excludeusers' ).val( ( getExcludedUsers() ).join( '\n' ) );
					$( '#gadget-recentchangesstream-close' ).click( function() {
						myDialog.close();
					} );
				};

				// Use the getTeardownProcess() method to perform actions whenever the dialog is closed.
				// This method provides access to data passed into the window's close() method
				// or the window manager's closeWindow() method.
				MyDialog.prototype.getTeardownProcess = function ( data ) {
					return MyDialog.super.prototype.getTeardownProcess.call( this, data )
					.first( function () {
						// Perform any cleanup as needed
						$( '.oo-ui-windowManager' ).remove();
					}, this );
				};

				// Make the window.
				myDialog = new MyDialog( {
					classes: [
						'gadget-recentchangesstream-dialog'
					]
				} );

				// Create and append a window manager, which will open and close the window.
				windowManager = new OO.ui.WindowManager();
				$( 'body' ).append( windowManager.$element );

				// Add the window to the window manager using the addWindows() method.
				windowManager.addWindows( [ myDialog ] );

				// Open the window!
				windowManager.openWindow( myDialog );

				$( 'input[name="gadget-recentchangesstream-prop"]' ).change( function() {
					var checkedprops = [];
					var checkedpropsstr;
					$( 'input[name="gadget-recentchangesstream-prop"]:checked' ).each( function( i, e ) {
						checkedprops.push( $( e ).val() );
					} );
					checkedpropsstr = checkedprops.join();
					if ( checkedpropsstr ) {
						localStorage.setItem( propkey, checkedpropsstr );
					} else {
						localStorage.removeItem( propkey );
					}
				} );
				$( '#gadget-recentchangesstream-limit' ).change( function() {
					var input = $( '#gadget-recentchangesstream-limit' ).val();
					if ( /^0+$/.test( input ) ) {
						localStorage.removeItem( limitkey );
					} else if ( /\d/.test( input ) ) {
						localStorage.setItem( limitkey, input );
					}
				} );
				$( 'input[name="gadget-recentchangesstream-type"]' ).change( function() {
					var checkedtypes = [];
					var checkedtypesstr;
					$( 'input[name="gadget-recentchangesstream-type"]:checked' ).each( function( i, e ) {
						checkedtypes.push( $( e ).val() );
					} );
					checkedtypesstr = checkedtypes.join();
					if ( checkedtypesstr ) {
						localStorage.setItem( typekey, checkedtypesstr );
					} else {
						localStorage.removeItem( typekey );
					}
				} );
				$( '#gadget-recentchangesstream-time' ).change( function() {
					var input = $( '#gadget-recentchangesstream-time' ).val();
					if ( /^0+$/.test( input ) ) {
						mw.storage.remove( timekey );
					} else if ( /\d/.test( input ) ) {
						mw.storage.set( timekey, input );
					}
				} );
				$( 'input[name="gadget-recentchangesstream-namespace"]' ).change( function() {
					var checkednamespaces = [];
					var checkednamespacesstr;
					$( 'input[name="gadget-recentchangesstream-namespace"]:checked' ).each( function( i, e ) {
						checkednamespaces.push( $( e ).val() );
					} );
					checkednamespacesstr = checkednamespaces.join();
					if ( checkednamespacesstr ) {
						localStorage.setItem( namespacekey, checkednamespacesstr );
					} else {
						localStorage.removeItem( namespacekey );
					}
				} );
				$( '#gadget-recentchangesstream-toponly' ).change( function( e ) {
					if ( $( e.currentTarget ).prop( 'checked' ) ) {
						localStorage.setItem( toponlykey, 'true' );
					} else {
						localStorage.removeItem( toponlykey );
					}
				} );
				$( '#gadget-recentchangesstream-excludeusers' ).change( function( e ) {
					var excludedusersinput = $( e.currentTarget ).val().trim();
					if ( excludedusersinput ) {
						mw.storage.set( excludeduserskey, excludedusersinput );
					} else {
						mw.storage.remove( excludeduserskey );
					}
				} );
				$( '#gadget-recentchangesstream-soundfile' ).change( function( e ) {
					var soundFileInput = $( e.currentTarget ).val().trim();
					localStorage.setItem( soundfilekey, soundFileInput );
				} );
			}
		} );
		$( '#mw-content-text' ).children( '.mw-parser-output' ).empty();
		$( '#mw-content-text' ).children( '.mw-parser-output' ).append( '<ul id="gadget-recentchangesstream-list"></ul>' );
		getActions();
		setInterval( getActions, Number( getTimeInterval() ) );
		mw.hook( 'svwikigadgetrecentchangesstream' ).add( function() {
			var excludedUsers = getExcludedUsers();
			if ( excludedUsers.length > 1 ) {
				$( '.gadget-recentchangesstream-user' ).each( function( i, e ) {
					if ( excludedUsers.includes( $( e ).text() ) ) {
						$( e ).closest( 'li' ).addClass( 'gadget-recentchangesstream-excludeduser' );
					}
				} );
			}
		} );
	} );
}