Benutzer:Jones/scripts.js

Aus PokéWiki
Zur Navigation springen Zur Suche springen

Hinweis: Leere nach dem Speichern 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: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
  • Opera: Extras → Internetspuren löschen … → Individuelle Auswahl → Den kompletten Cache löschen
  • Konqueror: Aktualisieren anklicken oder F5 drücken
(function($) {
	WikiScripts = function(modules)
	{
		var defaultModules = {
			"searchShortcuts": true,
			"regexSearch": false,
			"reloadRC": false,
			"hideUser": true,
			"serebii": false,
			"confirmPurge": true,
			"testLink": false,
			"draftSave": true
		}
		
		var modules = $.extend(defaultModules, modules);
		
		var moduleInstances = {};
		
		var createModuleInstance = function(moduleName)
		{
			switch(moduleName)
			{
				case "searchShortcuts":
					return new searchShortcutsModule();
				case "regexSearch":
					return new regexSearchModule();
				case "reloadRC":
					return new reloadRCModule();
				case "hideUser":
					return new hideUserModule();
				case "serebii":
					return new serebiiModule();
				case "confirmPurge":
					return new confirmPurgeModule();
				case "testLink":
					return new testLinkModule();
				case "draftSave":
					return new draftSaveModule();
				default:
					console.log("Kein Module mit Namen " + moduleName);
			}
		};
		
		this.enableAllModules = function()
		{
			$.each(modules, function(module, enabled) {
				modules[module] = true;
			});
		};
		
		this.enableModule = function(moduleName)
		{
			modules[moduleName] = true;
		};
		
		this.disableModule = function(moduleName)
		{
			modules[moduleName] = false;
		};

		this.disableAllModules = function()
		{
			$.each(modules, function(module, enabled) {
				modules[module] = false;
			});
		};
		
	
		this.init = function(moduleOptions)
		{
			$.each(modules, function(module, enabled) {
				if(enabled)
				{
					moduleInstances[module] = createModuleInstance(module);

					if(typeof moduleOptions != "undefined" && moduleOptions.hasOwnProperty(module))
					{
						moduleInstances[module].setOptions(moduleOptions[module]);
					}

					moduleInstances[module].init();
				}
			});
		};
	};
	
	var searchShortcutsModule = function()
	{
		this.setOptions = function(options) {};

		this.init = function()
		{
			window.setInterval(checkForReplaces, 1000);
		};
		
		var checkForReplaces = function()
		{
			if (Math.floor(($("#searchInput").val().indexOf(":")+1)/2) == 1) {
				var text = $("#searchInput").val();
				text = text.replace(/^[BbUu]:/, "Benutzer:");
				text = text.replace(/^[BbUu][DdTt]:/, "Benutzer Diskussion:");
				text = text.replace(/^[Dd]:/, "Datei:");
				text = text.replace(/^[Dd][DdTt]:/, "Datei Diskussion:");
				text = text.replace(/^[Hh]:/, "Hilfe:");
				text = text.replace(/^[Hh][DdTt]:/, "Hilfe Diskussion:");
				text = text.replace(/^[Kk]:/, "Kategorie:");
				text = text.replace(/^[Kk][DdTt]:/, "Kategorie Diskussion:");
				text = text.replace(/^[Mm]:/, "MediaWiki:");
				text = text.replace(/^[Mm][DdTt]:/, "MediaWiki Diskussion:");
				text = text.replace(/^[Pp]:/, "PokéWiki:");
				text = text.replace(/^[Pp][DdTt]:/, "PokéWiki Diskussion:");
				text = text.replace(/^[Ss]:/, "Spezial:");
				text = text.replace(/^[Tt]:/, "Diskussion:");
				text = text.replace(/^[Vv]:/, "Vorlage:");
				text = text.replace(/^[Vv][DdTt]:/, "Vorlage Diskussion:");
				$("#searchInput").val(text);
			}
		}
	};

	var regexSearchModule = function()
	{
		this.setOptions = function(options) {};

		this.init = function()
		{
			if (mw.config.get("wgAction") == "submit" || mw.config.get("wgAction") == "edit" || mw.config.get("wgPageName") == "Spezial:Vorlagen_expandieren")
			{
				$("html").keydown(function(e) {
					if (e.keyCode==73 && e.ctrlKey) {
						var findtext = /null/;
						findtext.compile(prompt('Zu suchender Text:'), "g");
						var replacetext = prompt('Zu ersetzender Text:');
						replacetext = replacetext.replace(/\\n/g, "\n");
						if (findtext != /null/ && replacetext != null) {
							// TODO: selected text
							if (mw.config.get("wgPageName") == "Spezial:Vorlagen_expandieren") {
								$("#input").val($("#input").val().replace(findtext, replacetext));
							}
							else {
								$("#wpTextbox1").val($("#wpTextbox1").val().replace(findtext, replacetext));
							}
						}
					}
				});
			}
		};
	};

	var reloadRCModule = function()
	{
		var options = {
			"reloadTime": 120,
			"reloadIfSearch": false
		};
		
		this.setOptions = function(newOptions)
		{
			options = $.extend(options, newOptions);
		};
		
		this.init = function()
		{
			if (mw.config.get("wgPageName") == "Spezial:Letzte_Änderungen")
			{
				window.setTimeout(reload, options["reloadTime"]*1000);
			}
		};
		
		var reload = function()
		{
			if (options["reloadIfSearch"] ||  $("#searchInput").val() == "")
			{
				location.reload();
			}
			else
			{
				// Make another attempt with half the timeout
				window.setTimeout(reload, options["reloadTime"]*500);
			}
		};
	};

	var hideUserModule = function()
	{
		var options = {
			"splitter": ";"
		};

		this.setOptions = function(newOptions)
		{
			options = $.extend(options, newOptions);
		};

		this.init = function()
		{
			if (window.location.href.indexOf("hideuser=") > 0)
			{
				var hideuser = window.location.href.substring(window.location.href.indexOf("hideuser=")+9);
				hideuser = hideuser.replace(/(\?|\&).*/, "");
				hideuser = hideuser.split(options["splitter"]);
				
				$(".mw-userlink").each(function() {
					var title = $(this).attr("title");
					title = title.replace(/Benutzer(in)?:/, "");
					title = title.replace(" (Seite nicht vorhanden)", "");
					title = title.replace(" ", "_");
					if($.inArray(title, hideuser) >= 0)
					{
						$(this).parents(".mw-changeslist-line").hide(); // The complete line
					}
				});
			}
		};
	};

	var serebiiModule = function()
	{
		var defaultCallback = function(url)
		{
			$("#gl-topbar-pw").after("<li id=\"serebii\"><a href=\"" + url + "\" target=\"_blank\" style=\"background: transparent url('//serebii.net/favicon.ico') no-repeat scroll left center; background-size:15px; padding-left: 17px;\">Serebii</a></li>");
		};

		var options = {
			"callback": defaultCallback,
			"parseLocations": true
		};

		this.setOptions = function(newOptions)
		{
			options = $.extend(options, newOptions);
		};

		this.init = function()
		{
			var categories = mw.config.get("wgCategories");

			if(options["parseLocations"] && $.inArray("PokéWiki:Orte-Projekt-Inhalt", categories) >= 0)
			{
				// Handle Pokéarth: http://serebii.net/pokearth/(region)/(ort).shtml
				// TODO: Handle generations (http://serebii.net/pokearth/(region)/(gen)/(ort).shtml)
				var region = "";
				if($.inArray("Kanto", categories) >= 0)
				{
					region = "kanto";
				}
				else if($.inArray("Johto", categories) >= 0)
				{
					region = "johto";
				}
				else if($.inArray("Hoenn", categories) >= 0)
				{
					region = "hoenn";
				}
				else if($.inArray("Sinnoh", categories) >= 0)
				{
					region = "sinnoh";
				}
				else if($.inArray("Einall", categories) >= 0)
				{
					region = "unova";
				}
				else if($.inArray("Kalos", categories) >= 0)
				{
					region = "kalos";
				}
				else if($.inArray("Alola", categories) >= 0)
				{
					region = "alola";
				}

				var engName = $(".interwiki-en > a").first().attr("title").replace(" – English", "").replace(/ /g, "").toLowerCase();

				// Remove the region name from route links
				if(engName.indexOf("route") > -1)
				{
					engName = engName.replace(region, "");
				}
				
				if(region == "" || engName == "")
				{
					return;
				}

				options["callback"]("http://serebii.net/pokearth/" + region + "/" + engName + ".shtml");
			}
		};
		
	};
	
	var confirmPurgeModule = function()
	{
		this.setOptions = function(options) {};

		this.init = function()
		{
			if(mw.config.get("wgAction") == "purge")
			{
			  $(".oo-ui-inputWidget-input").click();
			}
		};
	};
	
	var testLinkModule = function()
	{
		var defaultCallback = function(url)
		{
			$("#gl-topbar-pw").after("<li id=\"testwiki\"><a href=\"" + url + "\" style=\"background: transparent url('//greenchu.de/favicon.ico') no-repeat scroll left center; background-size:15px; padding-left: 17px;\">Testwiki</a></li>");
		};

		var options = {
			"callback": defaultCallback
		};

		this.setOptions = function(newOptions)
		{
			options = $.extend(options, newOptions);
		};

		this.init = function()
		{
			var link = location.href;

			if(link.indexOf("test.pokewiki.de") > -1)
			{
				link = link.replace("test.", "www.");
			}
			else
			{
				link = link.replace("www.", "test.");
			}
			
			options["callback"](link);
		};
	};

	var draftSaveModule = function()
	{
		var options = {
			"saveInterval": 120,
			"draftSection": false
		};

		this.setOptions = function(newOptions)
		{
			options = $.extend(options, newOptions);
		};

		// Variables
		var cacheKey = "jonesDraft_";
		var section = -1;
		var lastText = "";
		var lastSave = 0;
		var date;

		this.init = function()
		{
			// Nothing to do here
			if (mw.config.get("wgAction") != "submit" && mw.config.get("wgAction") != "edit")
			{
				return;
			}
			
			// Can't save anything -> warn the user
			if(typeof localStorage == "undefined")
			{
				alert("Das draftSave-Modul ist aktiviert, jedoch steht localStorage nicht zur Verfügung");
			}
			
			// Check whether we're editing a section
			if ($("input[name=wpSection]").val() != "")
			{
				section = $("input[name=wpSection]").val();
			}
			
			// We're editing a section but don't want to save drafts so end here
			if(section > -1 && !options["draftSection"])
			{
				return;
			}
			
			// Still here? Then build our cache key
			cacheKey += mw.config.get("wgArticleId");
			
			// Init our Date object
			date = new Date();
			
			// Check whether we have already something in our cache
			var cache = localStorage.getItem(cacheKey);
			if(cache != null)
			{
				cache = JSON.parse(cache);
				
				// We're editing the whole article so check those cases:
				// - We have a draft of a section and draftSection is true => Notify the user that that draft will be discarded in favor of the whole draft
				// - We have an old draft of the whole article so ask the user whether he wants to restore it, otherwise discard it
				if(section == -1)
				{
					var hasSectionDraft = false;
					var articleDraft = "";
					
					$.each(cache, function(sectionId, draft) {
						if(sectionId == -1)
						{
							articleDraft = draft;
						}
						else
						{
							hasSectionDraft = true;
						}
					});
					
					if(hasSectionDraft && options["draftSection"])
					{
						alert("Es existiert mindestens ein Entwurf eines einzelnen Abschnitts. Bei Änderungen am ganzen Artikel wird dieser Abschnittsentwurf gelöscht!");
					}
					
					if(articleDraft != "")
					{
						var restoreDraft = confirm("Es wurde ein alter Entwurf gefunden. Soll dieser wieder hergestellt werden?");
						
						if(restoreDraft)
						{
							lastText = articleDraft["text"];
						}
					}
				}
				// We're editing only a section so check those cases: (No need to check for the option as we won't reach this part in case we have a section)
				// - We have a draft of the whole article => Notify the user that we discard that draft (which won't affect drafts of other sections)
				// - We have an old draft of this section so ask the user whether we should restore this draft
				else
				{
					var sectionDraft = "";
					var hasArticleDraft = false;

					$.each(cache, function(sectionId, draft) {
						if(sectionId == -1)
						{
							hasArticleDraft = true;
						}
						else if(sectionId == section)
						{
							sectionDraft = draft;
						}
					});
					
					if(hasArticleDraft)
					{
						alert("Es existiert ein Entwurf des ganzen Artikels. Bei Änderungen an diesem Abschnitt wird dieser gelöscht!");
					}
					
					if(sectionDraft != "")
					{
						var restoreDraft = confirm("Es wurde ein alter Entwurf gefunden. Soll dieser wieder hergestellt werden?");
						
						if(restoreDraft)
						{
							lastText = sectionDraft["text"];
						}
					}
				}
				
				// If we've found an old text we need to populate it into the textbox
				if(lastText != "")
				{
					$("#wpTextbox1").val(lastText);
					console.log("Restored draft on load");
				}
				// Save the current text to make sure our diff works
				else
				{
					lastText = $("#wpTextbox1").val();
				}

				// Save the current time to make sure we're not prompting the user for the same drafts again
				lastSave = date.getTime();
			}

			// Handle the submit event. Note that it's seems pretty impossible to properly detect whether a page is really saved or just previewed
			// To circumvent those issues we just delete our local draft and hope mediawiki properly populates the data
			// In case we just preview the data our draftSaver is reinitialized then and we can resave our data
			// Not the prettiest thing to do but as long as there's no better way it should be the safest
			$("#editform").submit(function(e) {
				var cache = localStorage.getItem(cacheKey);
				// No cache, nothing to delete
				if(cache == null)
				{
					return;
				}
				// Editing the whole article -> we can delete everything
				if(section == -1)
				{
					localStorage.removeItem(cacheKey);
				}
				// Editing a section so remove that key from our array
				else
				{
					cache = JSON.parse(cache);
					delete cache[section];
					localStorage.setItem(cacheKey, JSON.stringify(cache));
				}
			});
			
			// Finally we can start our draft saver
			window.setTimeout(saveDraft, options["saveInterval"]*1000, true);
		};
		
		var saveDraft = function(checkCache)
		{
			// First check whether someone else modified our cache (ie another tab)
			var cache = localStorage.getItem(cacheKey);
			
			if(cache != null)
			{
				cache = JSON.parse(cache);
			}
			
			if(checkCache && cache != null)
			{
				var restore = false;
				
				// We're editing the whole article so check those cases but only check those drafts newer than our last one:
				// - We have a draft of a section and draftSection is true => Notify the user that that draft will be discarded in favor of the whole draft
				// - We have an old draft of the whole article so ask the user whether he wants to restore it, otherwise discard it
				if(section == -1)
				{
					var hasSectionDraft = false;
					var articleDraft = "";
					
					$.each(cache, function(sectionId, draft) {
						if(draft["time"] > lastSave)
						{
							if(sectionId == -1)
							{
								articleDraft = draft;
							}
							else
							{
								hasSectionDraft = true;
							}
						}
					});
					
					if(hasSectionDraft && options["draftSection"])
					{
						alert("Es wurde mindestens ein Abschnittsentwurf durch einen anderen Tab hinzugefügt. Weitere Änderungen löschen diesen!");
					}
					
					if(articleDraft != "")
					{
						var restoreDraft = confirm("Es wurde ein modifizierter Entwurf gefunden. Soll dieser wieder hergestellt werden?");
						
						if(restoreDraft)
						{
							lastText = articleDraft["text"];
							restore = true;
						}
					}
				}
				// We're editing only a section so check those cases but only check those drafts newer than our last one:
				// - We have a draft of the whole article => Notify the user that we discard that draft (which won't affect drafts of other sections)
				// - We have an old draft of this section so ask the user whether we should restore this draft
				else
				{
					var sectionDraft = "";
					var hasArticleDraft = false;

					$.each(cache, function(sectionId, draft) {
						if(draft["time"] > lastSave)
						{
							if(sectionId == -1)
							{
								hasArticleDraft = true;
							}
							else if(sectionId == section)
							{
								sectionDraft = draft;
							}
						}
					});
					
					if(hasArticleDraft)
					{
						alert("Es wurde ein neuer Entwurf des ganzen Artikels gefunden. Weitere Änderungen an diesem Abschnitt löschen diesen Entwurf!");
					}
					
					if(sectionDraft != "")
					{
						var restoreDraft = confirm("Es wurde ein modifizierter Entwurf gefunden. Soll dieser wieder hergestellt werden?");
						
						if(restoreDraft)
						{
							lastText = sectionDraft["text"];
							restore = true;
						}
					}
				}
				
				// If we've found an old text we need to populate it into the textbox
				if(restore)
				{
					$("#wpTextbox1").val(lastText);
					console.log("Restored modified draft");
				}
			}

			// Save the current time just to make sure we detect properly new changes from other tabs
			lastSave = date.getTime();

			// Nothing was modified so don't save anything (makes our life a little easier and we don't overwrite any other drafts if we don't need to. Also if we've restored something above we don't need to save it again)
			if(lastText == $("#wpTextbox1").val())
			{
				window.setTimeout(saveDraft, options["saveInterval"]*1000);
				return;
			}
			
			// Something was modified so build our new cache
			// If we haven't loaded a cache above we create an empty object to avoid any errors
			if(cache == null)
			{
				cache = {};
			}
			
			lastText = $("#wpTextbox1").val();
			// If we're editing the whole article life is easy: Just overwrite the whole object with the current draft
			if(section == -1)
			{
				cache = {"-1": {"time": lastSave, "text": lastText}};
			}
			// Otherwise we need to save our section and delete the draft for a whole artile
			else
			{
				delete cache["-1"];
				cache[section] = {"time": lastSave, "text": lastText};
			}
			
			localStorage.setItem(cacheKey, JSON.stringify(cache));
			console.log("Saved a new draft");
			window.setTimeout(saveDraft, options["saveInterval"]*1000);
		}
	};
	
}(jQuery));