MediaWiki:Gadget-AjaxEdit.js

"use strict";

// Description        : With a new button "Ædit" one can edit specific sections without reloading the whole page. //                      Supports TabbedLanguages gadget // Dependencies: mediawiki.util, mediawiki.Uri, mediawiki.user, mediawiki.api /* jshint maxerr:1048576, strict:true, undef:true, latedef:true, sub:true, esversion:5, esnext:false */ /* global mw, $ */

(function ajaxEditIife {	window.AjaxEdit = {};	window.AjaxEdit.scriptLink = "";	if (mw.config.get("wgSiteName") !== "Wiktionary")		window.AjaxEdit.scriptLink += "wikt:";	if (mw.config.get("wgContentLanguage") !== "en")		window.AjaxEdit.scriptLink += "en:";	window.AjaxEdit.scriptLink += "MediaWiki:Gadget-AjaxEdit.js";	var $document = $(document);	window.AjaxEdit.FireEvents = function {		// fire page load events like the [quotations ▼] thing		// see https://github.com/wikimedia/mediawiki/blob/master/resources/src/mediawiki.action/mediawiki.action.edit.preview.js		mw.hook("wikipage.content").fire($document);		mw.hook("wikipage.categories").fire($document);	};	window.AjaxEdit.Click = function (ajaxEditAnchor) {		if (ajaxEditAnchor.hasEditBox) {			mw.notify("This AjaxEdit edit box is already open.");			return;		} else {			ajaxEditAnchor.hasEditBox = true;		}

var elements = {}; var _query = new mw.Uri($(ajaxEditAnchor)				.parent				.find("a[href*='action=edit']")				.attr("href")).query, title = _query.title, section = _query.section; section = section.replace("T-", ""); //transclusions... var hdr = $(ajaxEditAnchor).parent.parent; var h2Parent = hdr.parent; if (h2Parent.hasClass("mw-heading")) { hdr = h2Parent; }		var sectionName = hdr.children(".mw-headline").first.text; if (window.tabbedLanguages && !hdr.is(":header")) { sectionName = window.tabbedLanguages[window.currentLanguageTab]; }		var data = { action: 'raw', title: title, section: section }; $.get(mw.util.wikiScript('index'), data).then(function (wikitext) {			var rowHeight = Math.min(15, 1 + wikitext.split("\n").length);			elements.textarea = $(" ")			.attr({ rows: rowHeight })			.addClass("mw-editfont-monospace")			.text(wikitext);			elements.textareaSummary = $(" ")			.attr({ type: "text", maxlength: 500, spellcheck: true, name: "wpSummary", })			.keydown(event, function { if (event.keyCode == 13) { // on enter elements.saveButton.click; }			});			function checkboxAndLabel(id, text) {				var checkbox = $(" ")				.attr({ "id": id, "type": "checkbox", });				var label = $(" ")				.attr("for", id)				.text(text);				return [checkbox, label];			}			var minorEdit = checkboxAndLabel("ajaxedit-minor-edit-checkbox", "Minor edit");			elements.minorEditCheckbox = minorEdit[0], elements.minorEditLabel = minorEdit[1];			elements.saveButton = $(" ")			.text("Save")			.click(function { elements.textarea.attr('disabled', true); elements.textareaSummary.attr('disabled', true); window.AjaxEdit.Save(section, sectionName, elements.textarea.val, title, elements.textareaSummary.val, elements.minorEditCheckbox.prop("checked")) .then(function (apiSaveResponse) {					if (apiSaveResponse.error) return; //if abusefilter was triggered					new mw.Api.get({page: mw.config.get("wgPageName"), action: "parse", prop: "text|categorieshtml"})					.then(function (newHtml) { $("#ajaxedit-wrapper").remove; $("#mw-content-text").html(newHtml.parse.text["*"]); $("#catlinks").replaceWith(newHtml.parse.categorieshtml["*"]); window.AjaxEdit.FireEvents; mw.loader.moduleRegistry["site"].state = "registered"; //mw.loader.moduleRegistry["site"].version="generate-unique-guid-here"; mw.loader.moduleRegistry["site"].script = undefined; mw.loader.using("site", function {}); window.AjaxEdit.Submain; });				});			})			.css("margin-left", "3px");			elements.cancelButton = $(' ')			.text("Cancel")			.click(function { $("#ajaxedit-wrapper").remove; ajaxEditAnchor.hasEditBox = false; });			elements.previewDiv = $(" ")			.css({ "border-style": "solid", "border-width": "1px 1px 1px 4px", "border-radius": "0.33em", "border-color": "#a3d3ff", })			.hide;			function timestamp {				return new Date.toISOString;			}			var previousText;			var previousTextTimestamp = timestamp;			function loadPreview {				var newText = elements.textarea.val;				var textTimestamp = timestamp;				if (!previousText || previousText != newText) {					new mw.Api					.parse( newText, { title: mw.config.get("wgPageName"), pst: "true", preview: "true", sectionpreview: "true", disableeditsection: "true" } )					.done(function (html) { if (textTimestamp > previousTextTimestamp) { elements.previewDiv.html(html); window.AjaxEdit.FireEvents; previousTextTimestamp = textTimestamp; }					});				}				previousText = newText;			}			var livePreview = checkboxAndLabel("ajaxedit-live-preview-checkbox", "Live preview");			elements.livePreviewCheckbox = livePreview[0], elements.livePreviewLabel = livePreview[1];			elements.livePreviewCheckbox.on("change", function { if ($(this).prop("checked")) { elements.previewDiv.show("slow"); loadPreview; this.previewIntervalId = setInterval(loadPreview, 500); } else { clearInterval(this.previewIntervalId); elements.previewDiv.hide("fast"); elements.previewDiv.empty; }			});			var wrapper = $(" ")			.attr("id", "ajaxedit-wrapper")			.css({ width: "auto", "margin": 0, "overflow": "hidden" })			.append(elements.textarea)			.append(elements.textareaSummary)			.append(elements.saveButton)			.append(elements.livePreviewCheckbox)			.append(elements.livePreviewLabel)			.append(elements.minorEditCheckbox)			.append(elements.minorEditLabel)			.append(elements.cancelButton)			.append(elements.previewDiv);			//tabbed languages support			if ($(ajaxEditAnchor).is("#tabstable .editlangsection a")) {				$(".languageContainer:not(:hidden)")				.first				.prepend(wrapper);			} else {				hdr.after(wrapper);			}		}); };	/*	 * Define edit summary template with window.AjaxEditSummary. For instance: window.AjaxEditSummary = "Æ $sectionlink $summary"; */	window.AjaxEdit.Save = function (sectionID, sectionName, sectionText, title, summary, minorEdit) { var finalSummary; if (typeof window.AjaxEditSummary === "string") { var usedSummary = false; finalSummary = window.AjaxEditSummary.replace(				/\$([a-zA-Z_][a-zA-Z0-9_]*)/g,				function(fullMatch, name) {					switch (name) {						case "summary": {							usedSummary = true;							return summary;						}						case "scriptlink": return window.AjaxEdit.scriptLink;						case "sectionname": return sectionText;						case "sectionlink": return "/* " + sectionName + " */";						default: {							mw.notify( "Your edit summary template (window.AjaxEditSummary) contains an unknown variable name. Variable name: " + name + ". Choose from summary, scriptlink, sectionname, sectionlink." );							return "";						}					}				}); if (!usedSummary) { mw.notify(					"Your edit summary template (window.AjaxEditSummary) doesn't use the edit summary you supplied, so your edit summary will be appended to the template: "					+ window.AjaxEditSummary); finalSummary += " " + summary; }		} else { finalSummary = "/* " + sectionName + " */ " + summary + " (using AjaxEdit)"; }		var data = { format: 'json', action: 'edit', title: title, section: sectionID, summary: finalSummary, text: sectionText, token: mw.user.tokens.get('csrfToken'), minor: minorEdit, };		return new mw.Api.post(data).then(function (response) {			if (response && response.edit && response.edit.result == 'Success') {				mw.notify("successful");			} else if (response && response.error) {				mw.notify('Error: API returned error code "' + response.error.code + '": ' + response.error.info);			}			return response;		}).fail(function (xhr) {			mw.notify('Error: Request failed.');			$('#ajaxedit-wrapper *').attr('disabled', false);		}); };	window.AjaxEdit.Submain = function {		$(".mw-body-content .mw-editsection > .mw-editsection-bracket:contains(']')").each (function{			var btn = $('').text("Ædit").on("click", function { window.AjaxEdit.Click(this) });			$(this).before(", ").before(btn);		}); };	window.AjaxEdit.Main = function {		$(".mw-editsection > .mw-editsection-bracket:contains(']')").each (function{			var btn = $('').text("Ædit").on("click", function { window.AjaxEdit.Click(this) });			$(this).before(", ").before(btn);		}); };

if (mw.config.get('wgAction') == "view") $(window.AjaxEdit.Main); });