میڈیاویکی:Gadget-WikiNotes.js

آزاد دائرۃ المعارف، ویکیپیڈیا سے

تفصیل کے لیے کھولیں کے بٹن پر کلک کریں یاددہانی: محفوظ کرنے کے بعد تازہ ترین تبدیلیوں کو دیکھنے کے لیے آپ کو اپنے براؤزر کا کیش صاف کرنا ہوگا۔

  • فائرفاکس/ سفاری: جب Reload پر کلک کریں تو Shift دبا کر رکھیں، یا Ctrl-F5 یا Ctrl-R دبائیں (Mac پر R- )
  • گوگل کروم: Ctrl-Shift-R دبائیں (Mac پر Shift-R-⌘)
  • انٹرنیٹ ایکسپلورر: جب Refresh پر کلک کریں تو Ctrl یا Ctrl-F5 دبائیں
  • اوپیرا: Tools → Preferences میں جائیں اور کیش صاف کریں

//[[Benutzer:Schnark/js/notizen]] <nowiki>
/*global mediaWiki*/

(function ($, mw) {
"use strict";

//jscs:disable maximumLineLength
var l10n = {
	en: {
		'pagetitle': '$1 - {{SITENAME}}',
		'brackets': '[$1]',

		'wikinotes': 'Wikinotes',
		'wikinotes-star': '\u2736',
		'wikinotes-minutes': 'minutes',
		'wikinotes-hours': 'hours',
		'wikinotes-days': 'days',
		'wikinotes-weeks': 'weeks',
		'wikinotes-months': 'months',
		'wikinotes-years': 'years',
		'wikinotes-date-format': '$1, $2:$3',
		'wikinotes-dateformat': 'd. M yy',
		'wikinotes-alarm': '<i>$2</i> on $1',
		'wikinotes-disable-alarm': '\u2713',
		'wikinotes-disable-alarm-title': 'disable alarm',
		'wikinotes-delete-note': '\u2715',
		'wikinotes-delete-note-title': 'delete note',
		'wikinotes-alarms': '{{PLURAL:$1|This note requires|These notes require}} your attention: $2',
		'wikinotes-no-notes': 'You did\'t add notes to any page.',
		'wikinotes-list-head': 'You added these notes to pages ($1 | $2 | $3):',
		'wikinotes-list-delete-all': 'delete all notes',
		'wikinotes-list-export-import': 'export/import',
		'wikinotes-bookmarklet': 'backup for Wikinotes',
		'wikinotes-bookmarklet-title': 'Install this link as bookmarklet to get a backup of your current notes',
		'wikinotes-export-import-notes': 'These data encoded as JSON represent your current notes. You can save them as backup, restore them when needed, or edit them.',
		'wikinotes-storage-error': 'A storage error occured, changes to the notes could not be saved.',
		'wikinotes-json-error': 'The JSON is not valid: $1',
		'wikinotes-list-page': 'page',
		'wikinotes-list-title': 'title',
		'wikinotes-list-alarm': 'alarm',
		'wikinotes-list-delete': 'delete note',
		'wikinotes-no-alarm': '(no alarm)',
		'wikinotes-list-alarm-rule': 'regularily all $1 $2',
		'wikinotes-delete-from-list': 'delete',
		'wikinotes-dialog': 'Add new note',
		'wikinotes-dialog-intro': 'This dialog allows you to add a new note and set an alarm for it if you want to.',
		'wikinotes-dialog-note': 'Note',
		'wikinotes-dialog-title': 'Title:',
		'wikinotes-dialog-content': 'Content:',
		'wikinotes-dialog-alarm': 'Alarm',
		'wikinotes-dialog-alarm-type': 'Type of alarm:',
		'wikinotes-dialog-alarm-type-none': 'no alarm',
		'wikinotes-dialog-alarm-type-once': 'once',
		'wikinotes-dialog-alarm-type-regular-times': 'alarm at regular times',
		'wikinotes-dialog-alarm-type-regular-period': 'alarm in regular periods',
		'wikinotes-dialog-alarm-time': 'Date:',
		'wikinotes-dialog-expire': 'Alarm expires after (0, if it should\'t expire):',
		'wikinotes-dialog-rule': 'Rule for alarms:',
		'wikinotes-dialog-save': 'Save',
		'wikinotes-dialog-cancel': 'Cancel',
		'wikinotes-error-date': 'Please enter a valid date in the future!',
		'wikinotes-error-rule': 'Pleas enter a valid number for the period of the alarm!',
		'wikinotes-error-expire': 'Please enter a valid number for the expiration!',
		'wikinotes-new': 'new note',
		'wikinotes-new-title': 'Opens dialog to add a new note'
	},
	ur: {
		'pagetitle': '$1 - {{SITENAME}}',
		'brackets': '[$1]',

		'wikinotes': 'ویکی اطلاعات',
		'wikinotes-star': '\u2736',
		'wikinotes-minutes': 'منٹ',
		'wikinotes-hours': 'گھنٹے',
		'wikinotes-days': 'دن',
		'wikinotes-weeks': 'ہفتے',
		'wikinotes-months': 'مہینے',
		'wikinotes-years': 'سال',
		'wikinotes-date-format': '$1, $2:$3',
		'wikinotes-dateformat': 'd. M yy',
		'wikinotes-alarm': '$1 پر <i>$2</i>',
		'wikinotes-disable-alarm': '\u2713',
		'wikinotes-disable-alarm-title': 'الارم غیر فعال کریں',
		'wikinotes-delete-note': '\u2715',
		'wikinotes-delete-note-title': 'اطلاع حذف کریں',
		'wikinotes-alarms': '{{PLURAL:$1|اس اطلاع|ان اطلاعات}} پر آپ کی توجہ درکار ہے: $2',
		'wikinotes-no-notes': 'آپ نے کسی بھی صفحے میں اطلاع نہیں لگائی ہے',
		'wikinotes-list-head': 'آپ نے درج ذیل اطلاعات ($1 | $2 | $3) صفحات میں لگائی ہیں:',
		'wikinotes-list-delete-all': 'تمام اطلاعات حذف کریں',
		'wikinotes-list-export-import': 'برآمد/درآمد',
		'wikinotes-bookmarklet': 'ویکی اطلاعات کا بیک اپ بنائیں',
		'wikinotes-bookmarklet-title': 'آپ کی موجودہ اطلاعات کا بیک اپ حاصل کرنے کے لیے اس ربط کو بطور بک مارک نصب کریں',
		'wikinotes-export-import-notes': 'These data encoded as JSON represent your current notes. You can save them as backup, restore them when needed, or edit them.',
		'wikinotes-storage-error': 'اسٹوریج نقص واقع ہوا ہے، اطلاعات میں کی گئی تبدیلیاں محفوظ نہیں ہو سکیں۔',
		'wikinotes-json-error': 'The JSON is not valid: $1',
		'wikinotes-list-page': 'صفحہ',
		'wikinotes-list-title': 'عنوان',
		'wikinotes-list-alarm': 'الارم',
		'wikinotes-list-delete': 'اطلاع حذف کریں',
		'wikinotes-no-alarm': '(کوئی الارم نہیں)',
		'wikinotes-list-alarm-rule': 'regularily all $1 $2',
		'wikinotes-delete-from-list': 'حذف کریں',
		'wikinotes-dialog': 'نئی اطلاع بنائیں',
		'wikinotes-dialog-intro': 'اس دریچے کے ذریعہ آپ نئی اطلاع بنا سکتے ہیں نیز آپ اپنی حسب مرضی اس پر ایک الارم بھی لگا سکتے ہیں۔',
		'wikinotes-dialog-note': 'اطلاع',
		'wikinotes-dialog-title': 'عنوان:',
		'wikinotes-dialog-content': 'مندرجات:',
		'wikinotes-dialog-alarm': 'الارم',
		'wikinotes-dialog-alarm-type': 'طرز الارم:',
		'wikinotes-dialog-alarm-type-none': 'کوئی الارم نہیں',
		'wikinotes-dialog-alarm-type-once': 'ایک بار',
		'wikinotes-dialog-alarm-type-regular-times': 'الارم باقاعدہ وقتوں پر',
		'wikinotes-dialog-alarm-type-regular-period': 'الارم باقاعدہ دورانیے میں',
		'wikinotes-dialog-alarm-time': 'تاریخ:',
		'wikinotes-dialog-expire': 'اس کے بعد الارم کی میعاد ختم ہو جائے گی (میعاد ختم نہ ہونے کے لیے 0 درج کریں):',
		'wikinotes-dialog-rule': 'الارم کے اصول:',
		'wikinotes-dialog-save': 'محفوظ کریں',
		'wikinotes-dialog-cancel': 'منسوخ کریں',
		'wikinotes-error-date': 'براہ کرم مستقبل میں درست تاریخ درج کریں!',
		'wikinotes-error-rule': 'براہ کرم الارم کے دورانیہ کے لیے درست نمبر درج کریں!',
		'wikinotes-error-expire': 'براہ کرم اختتام میعاد کے لیے درست نمبر درج کریں!',
		'wikinotes-new': 'نئی اطلاع',
		'wikinotes-new-title': 'نئی اطلاع بنانے کے لیے دریچہ کھولیں'
	},
	de: {
		'pagetitle': '$1 – {{SITENAME}}',
		'wikinotes': 'Wikinotizen',
		'wikinotes-minutes': 'Minuten',
		'wikinotes-hours': 'Stunden',
		'wikinotes-days': 'Tage',
		'wikinotes-weeks': 'Wochen',
		'wikinotes-months': 'Monate',
		'wikinotes-years': 'Jahre',
		'wikinotes-alarm': '<i>$2</i> auf $1',
		'wikinotes-disable-alarm-title': 'Alarm ausschalten',
		'wikinotes-delete-note-title': 'Notiz löschen',
		'wikinotes-alarms': '{{PLURAL:$1|Folgende Notiz erfordert|Folgende Notizen erfordern}} Aufmerksamkeit: $2',
		'wikinotes-no-notes': 'Du hast noch zu keiner Seite Notizen hinzugefügt.',
		'wikinotes-list-head': 'Folgende Notizen hast du zu Seiten hinzugefügt ($1 | $2 | $3):',
		'wikinotes-list-delete-all': 'alle Notizen löschen',
		'wikinotes-list-export-import': 'Export/Import',
		'wikinotes-bookmarklet': 'Sicherungskopie für Wikinotes',
		'wikinotes-bookmarklet-title': 'Installiere diesen Link als Bookmarklet um eine Sicherungskopie deiner aktuellen Notizen zu sichern',
		'wikinotes-export-import-notes': 'Folgende Daten im JSON-Format repräsentieren die aktuellen Notizen. Du kannst sie als Sicherungskopie speichern, bei Bedarf wiederherstellen oder nach Belieben ändern.',
		'wikinotes-storage-error': 'Ein Speicherfehler trat auf, Änderungen an den Notizen konnten nicht gespeichert werden.',
		'wikinotes-json-error': 'Die JSON-Daten sind nicht korrekt: $1',
		'wikinotes-list-page': 'Seite',
		'wikinotes-list-title': 'Titel',
		'wikinotes-list-alarm': 'Alarm',
		'wikinotes-list-delete': 'Notiz löschen',
		'wikinotes-no-alarm': '(kein Alarm)',
		'wikinotes-list-alarm-rule': 'regelmäßig alle $1 $2',
		'wikinotes-delete-from-list': 'löschen',
		'wikinotes-dialog': 'Neue Notiz erstellen',
		'wikinotes-dialog-intro': 'Mit diesem Dialog kannst du eine neue Notiz erstellen und – falls gewünscht – einen Alarm für sie einrichten.',
		'wikinotes-dialog-note': 'Notiz',
		'wikinotes-dialog-title': 'Titel:',
		'wikinotes-dialog-content': 'Inhalt:',
		'wikinotes-dialog-alarm': 'Alarm',
		'wikinotes-dialog-alarm-type': 'Art des Alarms:',
		'wikinotes-dialog-alarm-type-none': 'kein Alarm',
		'wikinotes-dialog-alarm-type-once': 'einmaliger Alarm',
		'wikinotes-dialog-alarm-type-regular-times': 'Alarm zu regelmäßigen Zeitpunkten',
		'wikinotes-dialog-alarm-type-regular-period': 'Alarm in regelmäßigen Abständen',
		'wikinotes-dialog-alarm-time': 'Zeitpunkt:',
		'wikinotes-dialog-expire': 'Alarm erlischt nach (0, falls er nicht automatisch erlöschen soll):',
		'wikinotes-dialog-rule': 'Häufigkeit des Alarms:',
		'wikinotes-dialog-save': 'Speichern',
		'wikinotes-dialog-cancel': 'Abbrechen',
		'wikinotes-error-date': 'Gib bitte einen korrekten Zeitpunkt an, der in der Zukunft liegt!',
		'wikinotes-error-rule': 'Gib bitte eine eine korrekte Zahl für die zeitlichen Abstände des regelmäßigen Alarms an!',
		'wikinotes-error-expire': 'Gib bitte eine korrekte Zahl für den automatischen Ablauf des Alarms an!',
		'wikinotes-new': 'neue Notiz',
		'wikinotes-new-title': 'Öffnet den Dialog zum Erstellen einer neuen Notiz'
	},
	'de-ch': {
		'wikinotes-list-alarm-rule': 'regelmässig alle $1 $2',
		'wikinotes-dialog-alarm-type-regular-times': 'Alarm zu regelmässigen Zeitpunkten',
		'wikinotes-dialog-alarm-type-regular-period': 'Alarm in regelmässigen Abständen',
		'wikinotes-error-rule': 'Gib bitte eine eine korrekte Zahl für die zeitlichen Abstände des regelmässigen Alarms an!'
	},
	'de-formal': {
		'wikinotes-no-notes': 'Sie haben noch zu keiner Seite Notizen hinzugefügt.',
		'wikinotes-list-head': 'Folgende Notizen haben Sie zu Seiten hinzugefügt ($1 | $2 | $3):',
		'wikinotes-bookmarklet-title': 'Installieren Sie diesen Link als Bookmarklet um eine Sicherungskopie Ihrer aktuellen Notizen zu sichern',
		'wikinotes-export-import-notes': 'Folgende Daten im JSON-Format repräsentieren die aktuellen Notizen. Sie können sie als Sicherungskopie speichern, bei Bedarf wiederherstellen oder nach Belieben ändern.',
		'wikinotes-dialog-intro': 'Mit diesem Dialog können Sie eine neue Notiz erstellen und – falls gewünscht – einen Alarm für sie einrichten.',
		'wikinotes-error-date': 'Geben Sie bitte einen korrekten Zeitpunkt an, der in der Zukunft liegt!',
		'wikinotes-error-rule': 'Geben Sie bitte eine eine korrekte Zahl für die zeitlichen Abstände des regelmäßigen Alarms an!',
		'wikinotes-error-expire': 'Geben Sie bitte eine korrekte Zahl für den automatischen Ablauf des Alarms an!'
	}
//jscs:enable maximumLineLength

}, sectLinksHook, cachedData, hasOwn = Object.prototype.hasOwnProperty;

function initL10N (l10n, keep) {
	var i, chain = mw.language.getFallbackLanguageChain();
	keep = $.grep(mw.messages.get(keep), function (val) {
		return val !== null;
	});
	for (i = chain.length - 1; i >= 0; i--) {
		if (chain[i] in l10n) {
			mw.messages.set(l10n[chain[i]]);
		}
	}
	mw.messages.set(keep);
}

function getCSS () {
	var star = mw.msg('wikinotes-star');
	return '#wikinotes-alarm { border: 3px solid red; }' +
		'aside.wikinote { display: block; border-radius: 1em; background-color: yellow;' +
			'padding: 0.2em; margin-right: 2em; min-width: 7em; float: left; }' +
		'aside.active-alarm { border: 3px solid red; }' +
		'aside.inactive-alarm h5::after { content: "' + star + '"; color: gray; font-size: 150%; }' +
		'aside.active-alarm h5::after { content: "' + star + '"; color: red; font-size: 170%; }' +
		'aside.wikinote .delete-note { float: right; }' +
		'label.disabled { color: #ccc; }' +
		'html.ve-activated .wikinotes-add-new, html.ve-activated .wikinote { display: none; }';
}

function isCompatible () {
	return window.localStorage && window.JSON;
}

function random () {
	return String(Math.floor(Math.random() * 10000 + 1));
}

function getData () {
	if (cachedData) {
		return cachedData;
	}
	var data = mw.storage.get('shuaib-wikinotes');
	if (data) {
		data = JSON.parse(data);
	} else {
		data = {};
	}
	cachedData = data;
	return data;
}

function setData (data) {
	if (!mw.storage.set('shuaib-wikinotes', JSON.stringify(data))) {
		window.alert(mw.msg('wikinotes-storage-error'));
		return;
	}
	cachedData = data;
}

function deleteData () {
	if (!mw.storage.remove('shuaib-wikinotes')) {
		window.alert(mw.msg('wikinotes-storage-error'));
		return;
	}
	cachedData = {};
}

function resetData () {
	cachedData = false;
}

function addNote (note) {
	var data = getData(), key = random();
	while (key in data) {
		key += random();
	}
	note.key = key;
	data[key] = note;
	setData(data);
	return key;
}

function updateNote (key, note) {
	var data = getData();
	$.extend(data[key], note);
	setData(data);
}

function deleteNote (key) {
	var data = getData();
	delete data[key];
	setData(data);
}

function exportImportNotes () {
	var data = getData();
	data = JSON.stringify(data);
	data = window.prompt(mw.msg('wikinotes-export-import-notes'), data);
	if (data !== null) {
		try {
			data = JSON.parse(data);
		} catch (e) {
			window.alert(mw.msg('wikinotes-json-error', String(e)));
			return;
		}
		setData(data);
	}
}

function nextTime (start, rule) {
	var date, toMS = {
		's': 1000,
		'm': 1000 * 60,
		'h': 1000 * 60 * 60,
		'd': 1000 * 60 * 60 * 24,
		'w': 1000 * 60 * 60 * 24 * 7
	};
	if (!rule) {
		return false;
	}
	if (rule.unit in toMS) {
		return start + toMS[rule.unit] * rule.count;
	}
	date = new Date(start);
	if (rule.unit === 'M') {
		date.setMonth(date.getMonth() + rule.count);
	} else {
		date.setFullYear(date.getFullYear() + rule.count);
	}
	return Number(date);
}

function updateExpiredAlarm (alarm) {
	do {
		alarm.time = nextTime(alarm.time, alarm.rule);
	} while (alarm.time && alarm.time + alarm.expire < $.now());
	if (!alarm.time) {
		return false;
	}
	return alarm;
}

function updateAlarm (alarm) {
	var time = nextTime(alarm.rule && alarm.rule.fromNow ? $.now() : alarm.time, alarm.rule);
	if (!time) {
		return false;
	}
	alarm.time = time;
	return alarm;
}

function updateAlarmFor (key) {
	updateNote(key, {alarm: updateAlarm(getData()[key].alarm)});
}

function updateExpiredNotes () {
	var key, data = getData(), note;
	for (key in data) {
		if (hasOwn.call(data, key)) {
			note = data[key];
			if (note.alarm && note.alarm.expire && note.alarm.time + note.alarm.expire < $.now()) {
				updateNote(key, {alarm: updateExpiredAlarm(note.alarm)});
			}
		}
	}
}

function getActiveAlarms () {
	var key, data = getData(), note, list = [];
	for (key in data) {
		if (hasOwn.call(data, key)) {
			note = data[key];
			if (note.alarm && note.alarm.time <= $.now()) {
				list.push(note);
			}
		}
	}
	return list;
}

function getNotesForPage () {
	var key, data = getData(), note, list = [];
	for (key in data) {
		if (hasOwn.call(data, key)) {
			note = data[key];
			if (note.page === mw.config.get('wgPageName')) {
				list.push(note);
			}
		}
	}
	return list;
}

function getAllNotes () {
	var key, data = getData(), list = [];
	for (key in data) {
		if (hasOwn.call(data, key)) {
			list.push(data[key]);
		}
	}
	return list;
}

function formatAlarm (note) {
	return mw.html.element('li', {'data-wikinoteskey': note.key}, new mw.html.Raw(
		mw.msg('wikinotes-alarm',
			mw.html.element('a', {href: mw.util.getUrl(note.page)}, note.page),
			note.title
		) + ' ' +
		mw.html.element('a', {
			href: '#',
			'class': 'disable-alarm',
			title: mw.msg('wikinotes-disable-alarm-title')
		}, mw.msg('wikinotes-disable-alarm'))
	));
}

function formatNote (note) {
	var classes = ['wikinote'];
	if (note.alarm) {
		if (note.alarm.time <= $.now()) {
			classes.push('active-alarm');
		} else {
			classes.push('inactive-alarm');
		}
	}
	return mw.html.element('aside', {
		'class': classes.join(' '),
		'data-wikinoteskey': note.key
	}, new mw.html.Raw(
		mw.html.element('a', {
			href: '#',
			'class': 'delete-note',
			title: mw.msg('wikinotes-delete-note-title')
		}, mw.msg('wikinotes-delete-note')) + '\n' +
		mw.html.element('h5', {}, note.title) + '\n' +
		mw.html.element('div', {}, note.content)
	));
}

function formatRow (note) {
	var alarm, unitToMsg = {
		m: 'wikinotes-minutes',
		h: 'wikinotes-hours',
		d: 'wikinotes-days',
		w: 'wikinotes-weeks',
		M: 'wikinotes-months',
		Y: 'wikinotes-years'
	};
	if (!note.alarm) {
		alarm = mw.msg('wikinotes-no-alarm');
	} else {
		alarm = (new Date(note.alarm.time)).toLocaleString();
		if (note.alarm.rule) {
			alarm += mw.html.element('br') +
				mw.msg('wikinotes-list-alarm-rule', note.alarm.rule.count, mw.msg(unitToMsg[note.alarm.rule.unit]));
		}
	}
	return mw.html.element('tr', {'data-wikinoteskey': note.key}, new mw.html.Raw([
		mw.html.element('td', {}, new mw.html.Raw(
			mw.html.element('a', {href: mw.util.getUrl(note.page + (note.section ? '#' + note.section : ''))},
				note.page.replace(/_/g, ' '))
		)),
		mw.html.element('td', {}, note.title),
		mw.html.element('td', {}, new mw.html.Raw(alarm)),
		mw.html.element('td', {}, new mw.html.Raw(
			mw.html.element('a', {href: '#', 'class': 'delete-note'}, mw.msg('wikinotes-delete-from-list'))
		))
	].join('')));
}

function readFromForm () {
	var data = {
		title: $('#wikinotes-title').val(),
		content: $('#wikinotes-content').val()
	}, alarmType, alarm, time, date, hour, minute, expire;
	alarmType = $('#wikinotes-alarm-type :selected').val();
	if (alarmType === 'none') {
		alarm = false;
	} else {
		date = Number($('#wikinotes-alarm-date-hidden').val());
		hour = Number($('#wikinotes-alarm-hour').val());
		minute = Number($('#wikinotes-alarm-minute').val());
		time = date + (hour * 60 + minute) * 60 * 1000;
		if (isNaN(time) || time <= $.now()) {
			return {error: mw.msg('wikinotes-error-date')};
		}
		if (alarmType === 'once') {
			alarm = {time: time};
		} else {
			alarm = {
				time: time,
				rule: {
					count: Number($('#wikinotes-alarm-rule-count').val()),
					unit: $('#wikinotes-alarm-rule-unit :selected').val()
				}
			};
			if (isNaN(alarm.rule.count) || alarm.rule.count <= 0) {
				return {error: mw.msg('wikinotes-error-rule')};
			}
			if (alarmType === 'regularPeriod') {
				alarm.rule.fromNow = true;
			}
		}
		expire = Number($('#wikinotes-alarm-expire').val()) * $('#wikinotes-alarm-expire-unit :selected').val();
		if (isNaN(expire) || expire < 0) {
			return {error: mw.msg('wikinotes-error-expire')};
		}
		if (expire > 0) {
			alarm.expire = expire;
		}
	}
	data.alarm = alarm;
	return data;
}

function onDeleteClick (e) {
	/*jshint validthis: true*///Event-Handler
	e.preventDefault();
	var $note = $(this).parents('.wikinote');
	deleteNote($note.data('wikinoteskey'));
	$note.remove();
}

function showOneNote (note, $content) {
	var $head = note.section && $content.find('[id="' + note.section.replace(/("|\\)/g, '\\$1') + '"]'), /*
			Ja, das ist ein komischer Selektor. Es kann sein, dass das gesuchte Element noch nicht im DOM des
			aktuellen Dokuments ist, also können wir document.getElementById nicht verwenden, sondern müssen
			.querySelectorAll bzw. Sizzle verwenden. Aber dazu darf die ID keine Sonderzeichen enthalten
			(Punkte würden etwa Klassen bedeuten), bzw. diese müssten durch Schrägstriche maskiert werden.
			Aber bei einem Klassenselektor müssen wir uns wesentlich weniger anstrengen alle diese Sonderzeichen
			zu ersetzen, da es nur die zwei sind. Auf die Performance hat das keinen Einfluss, da querySelectorAll
			grundsätzlich schnell ist und Sizzle auch nichts anderes machen kann, als alle Elemente durchzugehen
			und deren ID zu vergleichen.*/
		$note = $($.parseHTML(formatNote(note)));
	$note.find('.delete-note').click(onDeleteClick);
	if ($head && $head.length) {
		$head.parent('h1,h2,h3,h4,h5,h6').after($note);
	} else {
		$content.prepend($note);
	}
}

function showNotesForPage ($content) {
	if ($content.attr('id') !== 'mw-content-text') {
		return;
	}
	var i, list = getNotesForPage();
	if (list.length === 0) {
		return;
	}
	for (i = 0; i < list.length; i++) {
		showOneNote(list[i], $content);
	}
}

function showActiveAlarms () {
	var i, list = getActiveAlarms(), html = [];
	if (list.length === 0) {
		return;
	}
	for (i = 0; i < list.length; i++) {
		html.push(formatAlarm(list[i]));
	}
	html = mw.html.element('ul', {}, new mw.html.Raw(html.join('')));
	html = mw.html.element('div', {id: 'wikinotes-alarm'}, new mw.html.Raw(mw.msg('wikinotes-alarms', list.length, html)));
	$('#wikinotes-alarm').remove();
	$('#content').prepend(html);
	$('#wikinotes-alarm .disable-alarm').click(function (e) {
		e.preventDefault();
		var $this = $(this);
		updateAlarmFor($this.parents('li').data('wikinoteskey'));
		$this.remove();
	});
}

function showAllNotes () {
	var i, bookmarklet = 'javascript', list = getAllNotes(), html = [];
	document.title = mw.msg('pagetitle', mw.msg('wikinotes'));
	$('#firstHeading').html(mw.msg('wikinotes'));
	if (list.length === 0) {
		$('#mw-content-text').html(mw.msg('wikinotes-no-notes'));
		return;
	}
	bookmarklet += ':';
	bookmarklet += 'mw.libs.restoreWikinotes(' + JSON.stringify(getData()) + ')';
	html.push(mw.html.element('tr', {}, new mw.html.Raw([
		mw.html.element('th', {}, mw.msg('wikinotes-list-page')),
		mw.html.element('th', {}, mw.msg('wikinotes-list-title')),
		mw.html.element('th', {}, mw.msg('wikinotes-list-alarm')),
		mw.html.element('th', {}, mw.msg('wikinotes-list-delete'))
	].join(''))));
	for (i = 0; i < list.length; i++) {
		html.push(formatRow(list[i]));
	}
	html = mw.html.element('table', {id: 'wikinotes-table', 'class': 'wikitable'}, new mw.html.Raw(html.join('')));
	html = mw.html.element('p', {}, new mw.html.Raw(
		mw.msg('wikinotes-list-head',
			mw.html.element('a', {id: 'export-import-notes', href: '#'}, mw.msg('wikinotes-list-export-import')),
			mw.html.element('a', {id: 'delete-all-notes', href: '#'}, mw.msg('wikinotes-list-delete-all')),
			mw.html.element('a', {title: mw.msg('wikinotes-bookmarklet-title'), href: bookmarklet},
				mw.msg('wikinotes-bookmarklet'))
		)
	)) + html;
	$('#mw-content-text').html(html);
	$('tr .delete-note').click(function (e) {
		e.preventDefault();
		var $tr = $(this).parents('tr');
		deleteNote($tr.data('wikinoteskey'));
		$tr.remove();
	});
	$('#export-import-notes').click(function (e) {
		e.preventDefault();
		exportImportNotes();
	});
	$('#delete-all-notes').click(function (e) {
		e.preventDefault();
		deleteData();
		$('#wikinotes-table').remove();
	});
	mw.hook('wikipage.content').fire($('#mw-content-text'));
}

function showNewNoteDialog (section) {
	var html, $dialog;
	function onClose () {
		var note = readFromForm();
		if (note.error) {
			window.alert(note.error);
			return;
		}
		note.page = mw.config.get('wgPageName');
		if (section) {
			note.section = section;
		}
		addNote(note);
		$dialog.remove();
		showOneNote(note, $('#mw-content-text'));
	}
	function enableDisable () {
		var alarmType = $('#wikinotes-alarm-type :selected').val(),
			selAlarmInput = '#wikinotes-alarm-date, #wikinotes-alarm-hour, #wikinotes-alarm-minute,' +
				'#wikinotes-alarm-expire, #wikinotes-alarm-expire-unit',
			selRuleInput = '#wikinotes-alarm-rule-count, #wikinotes-alarm-rule-unit',
			selAlarmLabel = '[for="wikinotes-alarm-date"], [for="wikinotes-alarm-expire"]',
			selRuleLabel = '[for="wikinotes-alarm-rule-count"]';
		if (alarmType === 'none') {
			$(selAlarmInput + ',' + selRuleInput).prop('disabled', true);
			$(selAlarmLabel + ',' + selRuleLabel).addClass('disabled');
		} else if (alarmType === 'once') {
			$(selAlarmInput).prop('disabled', false);
			$(selAlarmLabel).removeClass('disabled');
			$(selRuleInput).prop('disabled', true);
			$(selRuleLabel).addClass('disabled');
		} else {
			$(selAlarmInput + ',' + selRuleInput).prop('disabled', false);
			$(selAlarmLabel + ',' + selRuleLabel).removeClass('disabled');
		}
	}

	html =
	mw.html.element('fieldset', {}, new mw.html.Raw(
		mw.html.element('legend', {}, mw.msg('wikinotes-dialog-note')) +
		mw.html.element('label', {'for': 'wikinotes-title'}, mw.msg('wikinotes-dialog-title')) + mw.html.element('br') +
		mw.html.element('input', {id: 'wikinotes-title', css: 'width: 100%;'}) + mw.html.element('br') +
		mw.html.element('label', {'for': 'wikinotes-content'}, mw.msg('wikinotes-dialog-content')) + mw.html.element('br') +
		mw.html.element('textarea', {id: 'wikinotes-content'})
	)) + mw.html.element('fieldset', {}, new mw.html.Raw(
		mw.html.element('legend', {}, mw.msg('wikinotes-dialog-alarm')) +
		mw.html.element('label', {'for': 'wikinotes-alarm-type'}, mw.msg('wikinotes-dialog-alarm-type')) +
			mw.html.element('br') +
		mw.html.element('select', {id: 'wikinotes-alarm-type', size: 1}, new mw.html.Raw(
			mw.html.element('option', {value: 'none', selected: true}, mw.msg('wikinotes-dialog-alarm-type-none')) +
			mw.html.element('option', {value: 'once'}, mw.msg('wikinotes-dialog-alarm-type-once')) +
			mw.html.element('option', {value: 'regularTimes'}, mw.msg('wikinotes-dialog-alarm-type-regular-times')) +
			mw.html.element('option', {value: 'regularPeriod'}, mw.msg('wikinotes-dialog-alarm-type-regular-period'))
		)) + mw.html.element('br') +
		mw.html.element('label', {'for': 'wikinotes-alarm-date'}, mw.msg('wikinotes-dialog-alarm-time')) +
			mw.html.element('br') +
		mw.msg('wikinotes-date-format',
			mw.html.element('input', {id: 'wikinotes-alarm-date', 'class': 'noime'}),
			mw.html.element('input', {id: 'wikinotes-alarm-hour', 'class': 'noime', size: 2, value: '12'}),
			mw.html.element('input', {id: 'wikinotes-alarm-minute', 'class': 'noime', size: 2, value: '00'})
		) + mw.html.element('input', {id: 'wikinotes-alarm-date-hidden', type: 'hidden'}) + mw.html.element('br') +
		mw.html.element('label', {'for': 'wikinotes-alarm-expire'}, mw.msg('wikinotes-dialog-expire')) +
			mw.html.element('br') +
		mw.html.element('input', {id: 'wikinotes-alarm-expire', 'class': 'noime', value: 0, size: 3}) + ' ' +
			mw.html.element('select', {id: 'wikinotes-alarm-expire-unit', size: 1}, new mw.html.Raw(
				mw.html.element('option', {value: 1000 * 60}, mw.msg('wikinotes-minutes')) +
				mw.html.element('option', {value: 1000 * 60 * 60}, mw.msg('wikinotes-hours')) +
				mw.html.element('option', {value: 1000 * 60 * 60 * 24, selected: true}, mw.msg('wikinotes-days')) +
				mw.html.element('option', {value: 1000 * 60 * 60 * 24 * 7}, mw.msg('wikinotes-weeks'))
			)) + mw.html.element('br') +
		mw.html.element('label', {'for': 'wikinotes-alarm-rule-count'}, mw.msg('wikinotes-dialog-rule')) +
			mw.html.element('br') +
		mw.html.element('input', {id: 'wikinotes-alarm-rule-count', 'class': 'noime', value: 1, size: 3}) + ' ' +
			mw.html.element('select', {id: 'wikinotes-alarm-rule-unit', size: 1}, new mw.html.Raw(
				mw.html.element('option', {value: 'h'}, mw.msg('wikinotes-hours')) +
				mw.html.element('option', {value: 'd', selected: true}, mw.msg('wikinotes-days')) +
				mw.html.element('option', {value: 'w'}, mw.msg('wikinotes-weeks')) +
				mw.html.element('option', {value: 'M'}, mw.msg('wikinotes-months')) +
				mw.html.element('option', {value: 'Y'}, mw.msg('wikinotes-years'))
			))
	));
	html = mw.html.element('p', {}, new mw.html.Raw(mw.msg('wikinotes-dialog-intro'))) +
		mw.html.element('p', {}, new mw.html.Raw(html));
	$dialog = $('<div>').html(html);
	$dialog.appendTo('body').dialog({
		title: mw.msg('wikinotes-dialog'),
		modal: true,
		width: '47em',
		close: function () {
			$dialog.remove();
		},
		buttons: [{
			text: mw.msg('wikinotes-dialog-save'),
			click: onClose
		}, {
			text: mw.msg('wikinotes-dialog-cancel'),
			click: function () {
				$dialog.remove();
			}
		}]
	});
	$('#wikinotes-alarm-date').datepicker({
		altField: '#wikinotes-alarm-date-hidden',
		altFormat: '@',
		autoSize: true,
		dateFormat: mw.msg('wikinotes-dateformat'),
		//defaultDate: 0,
		minDate: 0
	});
	$('#wikinotes-alarm-type').change(enableDisable).change();
}

function addNewNote (e) {
	/*jshint validthis: true*///Event-Handler
	var section = $(this).find('a').data('wikinotessection');
	e.preventDefault();
	mw.loader.using(['jquery.ui'], function () {
		showNewNoteDialog(section);
	});
}

function initAlarms () {
	updateExpiredNotes();
	$(function () {
		showActiveAlarms();
		window.setInterval(function () {
			resetData();
			showActiveAlarms();
		}, 5 * 60 * 1000);
	});
}

function initNew ($content) {
	if ($content.attr('id') !== 'mw-content-text') {
		return;
	}
	//TODO mw.hook('wikipage.title').add(...) und gleich wie section-links.js
	$content = $content.add($('#firstHeading').parent());
	$content.find('.wikinotes-add-new').remove();
	$content.find('h1,h2,h3,h4,h5,h6').each(function (i, h) {
		var $h = $(h), hash = $h.find('.mw-headline').attr('id') || '';
		if (i === 0 || hash !== '') {
			$h.append($('<span>')
				.addClass('wikinotes-add-new mw-editsection-like')
				.html(mw.msg('brackets', mw.html.element('a', {href: '#', title: mw.msg('wikinotes-new-title'),
					'data-wikinotessection': hash}, mw.msg('wikinotes-new'))))
			);
		}
	});
	$content.find('.wikinotes-add-new').click(addNewNote);
	if (!sectLinksHook) {
		mw.hook('userjs.section-links').add(function (callback, $content) {
			callback($content.find('.wikinotes-add-new'), mw.msg('wikinotes-new-title'), 'note');
		});
		sectLinksHook = true;
	}
}

function init () {
	initL10N(l10n, ['pagetitle', 'brackets']);
	mw.util.addCSS(getCSS());
	initAlarms();
	if (
		mw.config.get('wgNamespaceNumber') === -1 &&
		(mw.config.get('wgTitle') === 'Wikinotes' || mw.config.get('wgTitle') === mw.msg('wikinotes'))
	) {
		mw.config.set('wgCanonicalSpecialPageName', 'Wikinotes');
		$(showAllNotes);
	}
	mw.hook('wikipage.content').add(showNotesForPage).add(initNew);
}

if (mw.config.get('wgAction') === 'view' && isCompatible()) {
	mw.loader.using(['mediawiki.util', 'mediawiki.language', 'mediawiki.storage', 'mediawiki.jqueryMsg'], init);
}

if (isCompatible()) {
	mw.libs.restoreWikinotes = setData;
}

})(jQuery, mediaWiki);
//</nowiki>