Bikarhêner:Balyozxane/RhymesAdder.js

Ji Wîkîferhengê

Zanibe: Piştî weşandinê, ji bo dîtina guhartinan dibe ku hewce be "cache"ya geroka xwe paqij bikî.

  • Firefox / Safari: Pê li Shift û Reload bike an jî Ctrl-F5 an Ctrl-R bike (ji bo Mac: ⌘-R)
  • Google Chrome: Pê li Ctrl-Shift-R (ji bo Mac: ⌘-Shift-R) bike
  • Internet Explorer / Edge: Pê li Ctrl û Refresh bike, an jî Ctrl-F5 bike
  • Opera: Pê li Ctrl-F5 bike.
/* {{documentation}}<nowiki>
Dependencies: ext.gadget.Editor,ext.gadget.LanguageUtils,mediawiki.util,mediawiki.Uri

To do:
 * Make less ugly
 * Ability to remove/edit rhymes
 * Put rhyme template at the bottom of pronunciation section?
 * Add qualifier button
*/
/*jshint maxerr:1048576, strict:true, undef:true, latedef:true, es5:true */
/*global mw, WikiXml, importScript, importScriptURI, $ */
var numberOfRhymesAdded = 0;

// Derived from [[User:Erutuon/scripts/templateParser.js]].
function parseTemplate(templateText) {
	var parameters = new Object(null),
    	parameterRegex = /\|(?:([^=|}]+)=([^|}]+)|([^|}]+))/g,
		template = new Object(null);
	
	template.parameters = parameters;
	
	var match,
		index = 1,
		name = templateText.match(/^{{([^|}]+)/);
	
	if (name === null)
		throw new Error("Invalid template: no name.");
	
	template.name = name[1];
	
	while ((match = parameterRegex.exec(templateText)) !== null) {
		if (match[1]) {
			parameters[match[1]] = match[2];
		} else {
			parameters[index++] = match[3];
		}
	}
	
	return template;
}

function hasRhymeTemplate(wikitext, languageCode, rhyme) {
	// [[Template:Rhymes]] and [[Template:rhyme]] redirect to [[Template:rhymes]].
	// Simple regex is sufficient because there are no cases of {{rhymes}} with
	// nested templates in the dump.
	var match, rhymeTemplate = /{{[Rr]hymes?\|.+?}}/g;
	while ((match = rhymeTemplate.exec(wikitext)) !== null) {
		var template = parseTemplate(match[0]);
		var templateLanguageCode = template.parameters.lang || template.parameters[1];
		if (templateLanguageCode == languageCode) {
			for (var i = template.parameters.lang ? 1 : 2; template.parameters[i]; ++i) {
				if (template.parameters[i].trim() === rhyme)
					return true;
			}
		}
	}
	return false;
}

function setUpRhymeAdderFor(h3, div) {
	var findNumberOfHeaders = parseInt(new mw.Uri(h3.find("a").get(0).href).query.section);
	var addNewRhymeForm;
	editor = new Editor();
	new AdderWrapper(editor, {
		'createForm': function() {
			return addNewRhymeForm =
				$('<form>')
				.append(
					$('<label>+Beşavendeke nû: </label>')
					.append($('<input>').attr("name", 'rhyme'))
				)
				.append($('<input>').attr('type', 'submit').val('Lê zêde bike'))[0];
		},
		'fields': {
			'rhyme': function(txt, error) {
				return txt || error('Ji kerema xwe beşavendeke binivîse.');
			}
		},
		'onsubmit': function(values, render) {
			var langname = mw.config.get("wgTitle").split('/')[0];
			var lutils = new LanguageUtilsAsync();
			lutils.GetWiktionaryCodeByCanonicalName(langname).then(function(langcode) {
				$(addNewRhymeForm).find('input')[0].value = "";

				var newItem = '{{g|' + langcode + '|' + values.rhyme + '}}';
				render(newItem, function(newhtml) {
					var addedRhymeNode = $("<li>").html(newhtml),
						collator = window.Intl && new Intl.Collator( langcode, { "case": false } ),
						sortFunction = collator ? 
							collator.compare :
							function compare( a, b ) {
								return a.toUpperCase() < b.toUpperCase() ? -1 : 1;
							};
					editor.addEdit({
						'edit': function(wikitext) {
							var wikixml = WikiXml.parseWikitext(wikitext);
							var hdr = $(wikixml.find("section").get(findNumberOfHeaders - 1));
							var headerData = hdr.find("data").get(0).textContent;
							
							var rhymelistbegin_match = headerData.match(/{{beşavend-ser\|?[0-9]?}}/);
							var rhymelistbegin_index = rhymelistbegin_match.index + rhymelistbegin_match[0].length;
							var rhymelistend_index = headerData.indexOf("{{beşavend-bin}}");
							var rhymesPrefix = headerData.substring(0, rhymelistbegin_index);
							var rhymes = headerData.substring(rhymelistbegin_index, rhymelistend_index).trim().split(/\r?\n/);
							var rhymesSuffix = headerData.substring(rhymelistend_index);

							rhymes.push("* " + newItem);
							var canRearrange = true;

							var sortableLines = rhymes.map(function(line) {
								var m;
								m = line.match(/^\* ?{{g\|[a-zA-Z]{2,3}\|(.+)$/);
								if (m && m[1]) return [m[1], line];

								m = line.match(/^\* ?\[\[(.+)$/);
								if (m && m[1]) return [m[1], line];

								canRearrange = false;
								return null;
							});
							console.trace("canRearrange is " + canRearrange);

							if (canRearrange) {
								sortableLines.sort( function(a,b) { return sortFunction(a[0], b[0]);} );
								rhymes = sortableLines.map(function(sortableLine) {
									var match = sortableLine[1].match(/^\* ?\[\[(.+)]\]$/);
									if (match && match[1]) return "* {{g|" + langcode + "|" + match[1] + "}}";
									else return sortableLine[1];
								});
							}
							
							$(hdr.find("data").get(0)).text(rhymesPrefix + "\n" + rhymes.join("\n") + "\n" + rhymesSuffix);
							
							return WikiXml.toWikitext(wikixml);
						},
						'redo': function() {
							div.find("ul").append(addedRhymeNode);
							div.find("li").sort(function(a, b) {
								return sortFunction( $(a).text(), $(b).text() );
							}).appendTo(div.find("ul"));
						},
						'undo': function() {
							addedRhymeNode.remove();
						},
						'summary': "+beşavend [[" + values.rhyme + "]]",
						'after_save': function() {
							numberOfRhymesAdded++;
							document.body.style.cursor = 'wait';
							new mw.Api().edit(values.rhyme, function(text) {
								text = text.content;
								var rhymehome = mw.config.get("wgTitle").split("/")[1];
								if (hasRhymeTemplate(text, langcode, rhymehome)) {
									document.body.style.cursor = --numberOfRhymesAdded ? 'wait' : '';
									return $.Deferred().reject('rhyme already on page');
								}
								if (text.match('==' + langname + '==') && !text.match("\\{\\{rhymes(\\|lang=" + langcode + "\\|" + mw.util.escapeRegExp(rhymehome) + "|\\|" + mw.util.escapeRegExp(rhymehome) + "\\|lang=" + langcode + "|\\|" + mw.util.escapeRegExp(rhymehome) + ")\\}\\}")) {
									if (!String(text.match("==" + langname + "==[\\s\\S]*?(----|$)")).match("=Pronunciation=")) {
										text = text.replace(RegExp("(==" + langname + "==[\\s\\S]*?(?=\n=+(?=[^=])(?!(Etymology=|Alternative))))"), "$1\n===Pronunciation===\n");
									}
									text = text.replace(
										RegExp('(==' + langname + '==[\\s\\S]*?=+Pronunciation=+[\\s\\S]*?\n(?![\:\*]))'),
										'$1* {{rhymes|' + langcode + "|" + rhymehome + '}}\n'
									);
								}
								if (text) return {
									text: text,
									summary: "+rhyme [[" + mw.config.get("wgPageName") + "|" + "-" + rhymehome + "]]"
								};
								else {
									document.body.style.cursor = --numberOfRhymesAdded ? 'wait' : '';
									return $.Deferred().reject('problem text is false');
								}
							}).then(function() {
								document.body.style.cursor = --numberOfRhymesAdded ? 'wait' : '';
							});
						}
					}, addedRhymeNode[ 0 ]);
				});
			});
		}
	}, h3.parent()[0], div[0]);
}

function setUpRhymeAdder() {
	$(".rhymes-list-begin").each(function() {
		var div = $(this);
		if (div.prev().text().indexOf("kîte") != -1) {
			try {
				setUpRhymeAdderFor(div.prev(), $(this));
			} catch (e) {
				console.log(e);
			}
		}
	});
}


if (mw.config.get('wgNamespaceNumber') === 100 && mw.config.get("wgAction") == "view")
	$.getScript("//ku.wiktionary.org/w/index.php?title=User:Balyozxane/XMLize.js&action=raw", function() {
		$(setUpRhymeAdder);
	});

// </nowiki>