Benutzer:Prog/EditExtension.js

Aus Wikibooks

Hinweis: Leere nach dem Veröffentlichen 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/Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
  • Opera: Strg+F5
// <nowiki>

mw.loader.load('https://de.wikibooks.org/w/index.php?title=Benutzer:Prog/Tools.js&action=raw&ctype=text/javascript');


function getCaretPosition(textbox){
	var range = {'begin':0, 'end':0};

	if(document.selection && document.selection.createRange){ // IE / Opera
		textbox.focus();
		var selection = document.selection.createRange ();
		range.end = selection.text.length;

		selection.moveStart('character', -textbox.value.length);

		range.begin = selection.text.length;
		range.end += range.begin;
	}else if(textbox.selectionStart || textbox.selectionStart == '0'){ // Mozilla
		range.begin = textbox.selectionStart;
		range.end = textbox.selectionEnd;
	}

	return range;
}


function setCaretPosition(textbox, range){
	if(textbox.setSelectionRange){ // Mozilla
		textbox.focus();
		textbox.setSelectionRange(range.begin, range.end);
	}else if(textbox.createTextRange){ // IE / Opera
		var range = textbox.createTextRange();
		range.collapse(true);
		range.moveEnd('character', range.end);
		range.moveStart('character', range.begin);
		range.select();
	}
}



function textboxInsert(element){
	var selection = function(begin, end){
		return {
			'begin': begin,
			'end': end
		};
	}

	var wpTextbox = document.getElementById( 'wpTextbox1' );
	var wpSummary = $('#wpSummary');

	var range = getCaretPosition(wpTextbox);

	var call = element['Call'];

	for(var i = 0; i < call['PreBegin'].length; ++i){
		call['PreBegin'][i]();
	}

	if(element['Begin'] != ''){
		setCaretPosition(wpTextbox, selection(0, 0));
		insertTags(element['Begin'], '', '');
		range.begin += element['Begin'].length;
		range.end += element['Begin'].length;
	}

	for(var i = 0; i < call['PostBegin'].length; ++i){
		call['PostBegin'][i]();
	}

	if(element['Pre'] != ''){
		setCaretPosition(wpTextbox, selection(range.begin, range.begin));
		insertTags(element['Pre'], '', '');
		range.end += element['Pre'].length;
	}

	for(var i = 0; i < call['Middle'].length; ++i){
		call['Middle'][i]();
	}

	if(element['Post'] != ''){
		setCaretPosition(wpTextbox, selection(range.end, range.end));
		insertTags(element['Post'], '', '');
		range.end += element['Post'].length;
	}
	range.begin = range.end;

	for(var i = 0; i < call['PreEnd'].length; ++i){
		call['PreEnd'][i]();
	}

	if(element['End'] != ''){
		setCaretPosition(wpTextbox, selection($(wpTextbox).val().length, $(wpTextbox).val().length));
		insertTags(element['End'], '', '');
	}

	for(var i = 0; i < call['PostEnd'].length; ++i){
		call['PostEnd'][i]();
	}

	setCaretPosition(wpTextbox, range);


	if(element['Summary'] != ''){
		if(wpSummary.val() == ''){
			wpSummary.val(element['Summary']);
		}else{
			if(wpSummary.val().split(' & ').indexOf(element['Summary']) == -1){
				wpSummary.val(wpSummary.val() + ' & ' + element['Summary']);
			}
		}
	}

	if(element['Action'] != ''){
		window.onbeforeunload = null;
		var element = $('#wp'+element['Action']);
		if(element.length != 0){
			element.click();
		}else{
			alert('EditExtension: Can\'t find element with ID: ' + 'wp' + action);
		}
	}
}

function createEditHelper(){
	if(wgAction != 'edit' && wgAction != 'submit') return false;

	// Helfer
	var default_value = function(object, property, value){
		if(typeof object[property] == 'undefined') object[property] = value;
	};

	// Tastenkürzel-Support
	if(!$('#JSEditExtensionShortCutDisplay').length){
		$('#wpTextbox1').before($('<div id="JSEditExtensionShortCutDisplay" class="JSUnvisible"/>'));
	}
	var short_cut_display = $('#JSEditExtensionShortCutDisplay');

	var key_sequences = new MyMap();
	var key_sequence = '';
	$('#wpTextbox1').keypress(function(event){
		if(event.ctrlKey  || !event.altKey || !event.metaKey){
			key_sequence = '';
			return true;
		}

		short_cut_display.removeClass('JSUnvisible');

		switch(event.keyCode){
		case 8:  key_sequence = key_sequence.substr(0, key_sequence.length-1); break;
		case 27: key_sequence = ''; break;
		default:
			if(event.charCode == 0)return true;
			key_sequence += String.fromCharCode(event.charCode);
		}

		short_cut_display.text(key_sequence);
		if(key_sequences.exists(key_sequence)){
			short_cut_display.addClass('JSEditExtensionShortCutMatch');
		}else{
			short_cut_display.removeClass('JSEditExtensionShortCutMatch');
		}

		return false;
	}).keyup(function(event){
		if(event.shiftKey || event.ctrlKey || (
			(event.altKey || !event.metaKey || event.keyCode != 0) &&
			(!event.altKey || event.metaKey || event.keyCode != 18)
		)) return true;

		short_cut_display.text(key_sequence);
		short_cut_display.addClass('JSUnvisible');

		if(!key_sequences.exists(key_sequence)) return false;

		$('#'+key_sequences.get(key_sequence)).click();
		key_sequence = '';

		return false;
	});


	// Setzte Standard-Werte
	var standard_id = 'JSEditExtensionStandard';

	// Standardbox erstellen, falls nicht vorhanden
	if(!$('#'+standard_id).length){
		$('#editpage-copywarn').before($('<div id="'+standard_id+'" />'));
	}

	// Existiert Konfigurationsfunktion?
	if(!$.isFunction(EditExtensionConfig)){
		throw new Error('EditExtension: "EditExtensionConfig" is not a function.');
		return false;
	}

	// Hole Konfiguration
	var config = EditExtensionConfig();

	// Konfiguration auf "syntaktische" Gültigkeit testen
	if(!$.isArray(config)){
		throw new Error('EditExtension: "EditExtensionConfig()" have to return an Array of Objects.');
	}
	var errors = '';
	$.each(config, function(group_index, group){
		default_value(group, 'Namespace', []);
		default_value(group, 'Position', '');
		default_value(group, 'Titleprefix', '');
		default_value(group, 'Elements', []);
		$.each(group, function(group_key, group_value){
			switch(group_key){
			case 'Namespace':
				if(!$.isArray(group_value)){
					errors += '\nconfig['+group_index+']['+group_key+']'+' is not an array of numbers.';
					break;
				}
				$.each(group_value, function(namespace_index, namespace){
					if(typeof namespace == 'number') return true;
					errors += '\nconfig['+group_index+']['+group_key+']'+'['+namespace_index+'] is not a number.';
				});
				break;
			case 'Position':
				if(typeof group_value != 'string'){
					errors += '\nconfig['+group_index+']['+group_key+']'+' is not a string.';
					break;
				}
				if(group_value == '') group[group_key] = standard_id;
				break;
			case 'Titleprefix':
				if(typeof group_value != 'string'){
					errors += '\nconfig['+group_index+']['+group_key+']'+' is not a string.';
				}
				break;
			case 'Elements':
				if(!$.isArray(group_value)){
					errors += '\nconfig['+group_index+']['+group_key+']'+' is not an array.';
					break;
				}
				$.each(group_value, function(element_index, element){
					if(typeof element != 'object'){
						errors += '\nconfig['+group_index+']['+group_key+']'+'['+element_index+'] is not an object.';
						return true;
					}
					default_value(element, 'Name', '');
					default_value(element, 'Summary', '');
					default_value(element, 'Begin', '');
					default_value(element, 'End', '');
					default_value(element, 'Pre', '');
					default_value(element, 'Post', '');
					default_value(element, 'Action', '');
					default_value(element, 'Key', '');
					default_value(element, 'Call', {});
					$.each(element, function(element_key, element_value){
						switch(element_key){
						case 'Name':
						case 'Summary':
						case 'Begin':
						case 'End':
						case 'Pre':
						case 'Post':
						case 'Action':
						case 'Key':
							if(typeof element_value != 'string'){
								errors += '\nconfig['+group_index+']['+group_key+']['+element_key+']'+' is not a string.';
							}
							break;
						case 'Call':
							if(typeof element_value != 'object'){
								errors += '\nconfig['+group_index+']['+group_key+']['+element_key+']'+' is not an object.';
								break;
							}
							default_value(element_value, 'PreBegin', []);
							default_value(element_value, 'PostBegin', []);
							default_value(element_value, 'Middle', []);
							default_value(element_value, 'PreEnd', []);
							default_value(element_value, 'PostEnd', []);
							$.each(element_value, function(call_key, call_list){
								switch(call_key){
								case 'PreBegin':
								case 'PostBegin':
								case 'Middle':
								case 'PreEnd':
								case 'PostEnd':
									if(!$.isArray(call_list)){
										errors += '\nconfig['+group_index+']['+group_key+']['+element_key+']['+element_value+']'+' is not an array.';
										break;
									}
									$.each(call_list, function(callback_index, callback){
										if(typeof callback == 'function') return true;
										errors += '\nconfig['+group_index+']['+group_key+']['+element_key+']['+element_value+']['+callback_index+']'+' is not a function.';
									});
									break;
								default:
									errors += '\nconfig['+group_index+']['+group_key+']'+'['+element_index+']['+element_value+'] Unknown call-key: ' + call_key;
								}
							});
							break;
						default:
							errors += '\nconfig['+group_index+']['+group_key+']'+'['+element_index+'] Unknown element-key: ' + group_key;
						}
					});
				});
				break;
			default:
				errors += '\nUnknown group-key: config['+group_index+']' + group_key;
			}
		});
	});
	if(errors != ''){
		throw new Error('EditExtension: config-check:' + errors);
	}


	// Listen erstellen
	var idadd = 0;
	$.each(config, function(group_index, group){
		if(group['Namespace'].length && $.inArray(wgNamespaceNumber, group['Namespace']) == -1) return true;
		if(group['Titleprefix'] != wgTitle.substr(0, group['Titleprefix'].length)) return true;

		var input_box = $('#' + group['Position']);
		if(input_box.length == 0){
			throw new Error('EditExtension: Can\'t find HTML-Tag with ID ' + group['Position']);
		}

		var element_box = $('<div class="JSEditExtensionSeperator" />');

		$.each(group['Elements'], function(element_index, element){
			var id = 'JSEditExtensionLink_' + idadd; ++idadd;
			var link = $('<span class="JSEditExtensionLink" id="' + id + '">' + element['Name'] + '</span>');
			if(element['Key'] != '') link.attr('title', element['Key']);

			$.each(element['Call'], function(call_key, call_list){
				$.each(call_list, function(callback_index, callback){
					callback.id      = id;
					callback.element = element;
				});
			});

			link.click(function(){
				textboxInsert(element);
				return false;
			});

			if(element['Key'] != ''){
				if(key_sequences.exists(element['Key'])){
					alert(
						'EditExtension-Warning: Double shortcut (' + element['Key'] + ')\n' +
						'First use in #' + key_sequences.get(element['Key']) + '\n' +
						'Second use in #' + id + '\n' +
						'Only second use will work.'
					);
				}
				key_sequences.set(element['Key'], id);
			}

			element_box.append($('<span class="JSEditExtensionElement" />').append(link));
		});

		input_box.append(element_box);
	});

	return true;
}

$(createEditHelper);

mw.loader.load('https://de.wikibooks.org/w/index.php?title=Benutzer:Prog/EditExtension.css&action=raw&ctype=text/css', 'text/css');

// </nowiki>