跳转到内容

MediaWiki:Gadget-AjaxEdit.js

維基詞典,自由的多語言詞典

注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
  • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
  • Internet Explorer / Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5
  • Opera:Ctrl-F5


"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") !== "zh")
		window.AjaxEdit.scriptLink += "zh:";
	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(wgULS("该AjaxEdit编辑框已打开", "該AjaxEdit編輯框已打開。"));
			return;
		}

		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 sectionName = hdr.children(":header").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 = $("<textarea/>")
			.attr({ rows: rowHeight })
			.addClass("mw-editfont-monospace")
			.text(wikitext);
			
			elements.textareaSummary = $("<input/>")
			.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 = $("<input/>")
				.attr({
					"id": id,
					"type": "checkbox",
				});
				var label = $("<label/>")
				.attr("for", id)
				.text(text);
				return [checkbox, label];
			}
			
			var minorEdit = checkboxAndLabel("ajaxedit-minor-edit-checkbox", wgULS("小编辑", "小編輯"));
			elements.minorEditCheckbox = minorEdit[0], elements.minorEditLabel = minorEdit[1];
			
			elements.saveButton = $("<button/>")
			.text("保存")
			.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();
						ajaxEditAnchor.hasEditBox = false;
						$("#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 = $('<button/>')
			.text("取消")
			.click(function () {
				$("#ajaxedit-wrapper").remove();
				ajaxEditAnchor.hasEditBox = false;
			});
			elements.previewDiv = $("<div/>")
			.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", wgULS("实时预览", "實時預覽"));
			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 = $("<div/>")
			.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);
			}
			
			ajaxEditAnchor.hasEditBox = true;
		});
	};
	
	/*
	 * 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(
								wgULS(
									"您的编辑摘要模板(window.AjaxEditSummary)含有未知变量名:"
									+ name + "。请使用summary、scriptlink、sectionname、sectionlink。",
									"您的編輯摘要模板(window.AjaxEditSummary)含有未知變數名:"
									+ name + "。請使用summary、scriptlink、sectionname、sectionlink。"
								)
							);
							return "";
						}
					}
				});
			if (!usedSummary) {
				mw.notify(
					wgULS(
						"您的编辑摘要模板(window.AjaxEditSummary)不会使用您提供的编辑摘要,因此您的编辑摘要将后接于模板:"
						+ window.AjaxEditSummary,
						"您的編輯摘要模板(window.AjaxEditSummary)不會使用您提供的編輯摘要,因此您的編輯摘要將後接於模板:"
						+ window.AjaxEditSummary)
					);
				finalSummary += " " + summary;
			}
		} else {
			finalSummary = "/* " + sectionName + " */ " + summary + "(via [[" + window.AjaxEdit.scriptLink + "|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("成功");
			} else if (response && response.error) {
				mw.notify(wgULS('错误:API返回错误代码“' + response.error.code + '”:' + response.error.info, '錯誤:API返回錯誤碼「' + response.error.code + '」:' + response.error.info));
			}
			return response;
		}).fail(function (xhr) {
			mw.notify(wgULS('错误:无法发送请求。', '錯誤:無法發送請求。'));
			$('#ajaxedit-wrapper *').attr('disabled', false);
		});
	};
	
	window.AjaxEdit.Submain = function()
	{
		$(".mw-body-content .mw-editsection > .mw-editsection-bracket:contains(']')").each (function(){
			var btn = $('<a/>').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 = $('<a/>').text("Ædit").on("click", function() { window.AjaxEdit.Click(this) });
			$(this).before(", ").before(btn);
		});
	};

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