Jump to content

User:Bernanke's Crossbow/ModifiedIME.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Bernanke's Crossbow (talk | contribs) at 22:30, 13 August 2022 (Convert left/right to dbl/single click). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/*  Coordinatizing an HTML
	image map can be hard for you.  
	What vision is made from numbers?  
	This script lets you see as you do.  
    
	Version as of eight/thirteen/twenty-two.  
	Original script by Peter Schlömer 
	modified by	[[:he:user:קיפודנחש]]
	and also Bernanke's Crossbow.  
	
	The original script
	displays a copyright warning.  
	
	It says: (https://tools.wmflabs.org/imagemapedit/ime.js)
		Copyright (c) 2007-2013 Peter Schlömer

		Released under the following licenses (to make reuse in other Wikis
		easier):

		GNU General Public License (GPL), version 2
		GNU Free Documentatin Licence (GFDL), version 1.2 or later
		Creative Commons Attribution ShareAlike (CC-by-sa), version 2 or later
*/

//<nowiki>
/*jshint esversion: 6 */
if (mw.config.get('wgNamespaceNumber') == 6 &&
	mw.config.get('wgAction') == 'view')
	$(function () {
		"use strict";
		//Ensure idempotence, in case (eg)
		//[[m:Special:MyPage/global.js]] and main wiki both activate the script
		if (window.mw_ime_running) return;
		window.mw_ime_running = true;

		//General utilities
		const util = {
			//Localize error messages to your favorite language
			translations: {
				error_imagenotfound:
					'ImageMapEdit: Could not find image in page structure.'
			},
			//Translate texts
			translate() {
				for (const trans of [this.translations, window.ime_translations])
					if (trans) for (const key in trans)
						$('.ime_t_' + key).text(trans[key]);
			},
			std_handler(fct) {
				return e => {
					e.PreventDefault();
					fct();
				};
			},
			displayErr(message) {
				//First try on screen
				const jqFile = $('#file'); if (jqFile.length !== 0) {
					const errBox =
						$('<p>')
							.css({
								'color': 'darkred',
								'background': 'white',
								'border': '1px solid darkred',
								'padding': '1ex'
							})
							.text(message);
					const jqIme = $('#ime');
					if (jqIme !== 0) jqIme.before(errBox);
					else errBox.appendTo(jqFile);
				}
				//Can't find a good location
				else window.alert(message);
			},
			makeDiv(id) {
				const div = document.createElement('div');
				if (id) div.id = id;
				return div;
			},
			//Try to find an <a> tag within the specified HTML document node.
			findHyperlink(node) {
				//Look at the first child until it is none or <a>
				let a = node;
				while (a && a.nodeName.toUpperCase() != 'A')
					a = a.firstChild;
				return a;
			},
			all(arr) { return arr.reduce((a, b) => a && b); }
		};
		//Keep track of recent clicks
		const mouse = {
			listening: false,
			currentClicks: {},
			relax() {
				this.listening = false;
				this.currentClicks = {};
				ime.jcanvas.css({ cursor: '' });
			},
			listen() {
				this.listening = true;
				ime.jcanvas.css({ cursor: 'crosshair' });
			},
			fired(event) {
				if (!this.listening) return;
				event.preventDefault();
				event.stopPropagation();
				const offset = $('#imeImg').offset();
				const
					x = event.pageX - offset.left,
					y = event.pageY - offset.top;
				const position = {
					x: parseInt(x / ime.scale),
					y: parseInt(y / ime.scale)
				};
				const dblClick = event.detail > 1;
				if(dblClick) this.currentClicks.left = position;
				else this.currentClicks.right = position;
				ime.store(dblClick);
			}
		};
		//Highlighted areas
		const areas = Array();
		areas.current = function () { return this[state.currentlyEditing]; };
		areas.make = function (shape) {
			mouse.listen();
			this.push({ shape: shape, coords: [], link: '' });
			state.currentlyEditing = this.length - 1;
			this.update();
			return areas.current();
		};
		areas.update = function () {
			this.updateSelection();
			this.edit(state.currentlyEditing);
			updateResult();
		};
		areas.updateSelection = function () {
			this.selection.children().remove();
			for (let i = 0; i < this.length; i++) {
				const area = this[i],
					title = (area.title || area.link || '') + ' [' + area.shape + ']';
				$('<option>', { value: i })
					.text(title)
					.prop({ selected: i == state.currentlyEditing })
					.appendTo(this.selection);
			}
			this.selection.prop('selectedIndex', state.currentlyEditing);
		};
		areas.edit = function (index) {
			$('#imeProps').toggle(false);

			const area = this[index];
			mouse.currentClicks = area.clicks || {};
			if (area) {
				state.currentlyEditing = index;

				$('#imeProps').toggle(true);
				$('.ime-prop').toggle(false);
				$('.ime-prop-' + area.shape).toggle(true);

				mouse.listen();
				updateInputs();
			}
			this.draw();
		};
		areas.remove = function () {
			mouse.relax();
			// Remove element from this array
			this.splice(state.currentlyEditing, 1);
			if (state.currentlyEditing >= this.length)
				state.currentlyEditing = this.length - 1;
			this.update();
			if (state.currentlyEditing >= 0)
				this.edit(state.currentlyEditing);
		};
		areas.draw = function () { // this is where the magic is done.
			function markPoint(point, color) {
				if (point) {
					context.beginPath();
					const arm = 8 / ime.scale;
					context.moveTo(point.x + arm, point.y);
					context.lineTo(point.x - arm, point.y);
					context.moveTo(point.x, point.y + arm);
					context.lineTo(point.x, point.y - arm);
					context.strokeStyle = color;
					context.stroke();
					context.closePath();
				}
			}

			function drawPoly(coords) {
				coords = coords.slice();
				context.moveTo(coords.shift(), coords.shift());
				while (coords.length)
					context.lineTo(coords.shift(), coords.shift());
			}

			context.clearRect(0, 0, context.canvas.width / ime.scale, context.canvas.height / ime.scale); // prepare for a new day.
			for (let ind = 0; ind < this.length; ++ind) {
				const current = ind == state.currentlyEditing;
				context.fillStyle = current ? 'rgba(255,255,0,0.4)' : 'rgba(255,0,0,0.4)';
				const area = this[ind];
				const coords = area.coords;
				context.beginPath();
				switch (area.shape) {
					case 'rect':
						if (coords.length != 4) util.displayErr("Too many coordinates in rect");
						if (utils.all(coords)) //?
							drawPoly([coords[0], coords[1], coords[0], coords[3], coords[2], coords[3], coords[2], coords[1]]);
						break;
					case 'circle':
						if (coords.length != 3) util.displayErr("Too many coordinates in circ");
						//x,y,r,startAngle,endAngle
						context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2);
						break;
					case 'poly':
						drawPoly(coords);
						break;
				}
				context.closePath();
				context.fill();
				if (current) {
					context.strokeStyle = 'red';
					context.stroke();
				}
			}
			markPoint(mouse.currentClicks.left, 'red');
			if (this.current().shape != 'poly')
				markPoint(mouse.currentClicks.right, 'yellow');
		};

		const ime = {
			//Remove UI elements that might interfere 
			//(Wikimedia Commons 'annotations' feature)
			trimUI() { $('#ImageAnnotationAddButton').remove(); },
			store(leftClick) {
				const area = areas.current();
				area.link = document.ime.areaLink.value;
				area.title = document.ime.areaTitle.value;
				const d = area.clicks = $.extend({}, mouse.currentClicks);

				const full = d.left && d.right;
				switch (area.shape) {
					case 'rect':
						if (d.left) {
							area.coords[0] = d.left.x; area.coords[1] = d.left.y;
						}
						if (d.right) {
							area.coords[2] = d.right.x; area.coords[3] = d.right.y;
						}
						break;
					case 'circle':
						if (leftClick) {
							area.coords[0] = d.left.x; area.coords[1] = d.left.y;
						}
						if (full) {
							var dx = d.left.x - d.right.x,
								dy = d.left.y - d.right.y;
							area.coords[2] = parseInt(Math.sqrt(dx * dx + dy * dy));
						}
						break;
					case 'poly':
						if (leftClick && d.left)
							area.coords.push(d.left.x, d.left.y);
						break;
				}
				updateInputs(full || area.shape == 'poly');
				areas.update();
			},
			imports: {
				make() {
					for (const line of document.ime.importText.value.split("\n")) {
						const detect = {
							rect: /^rect +(\d+) +(\d+) +(\d+) +(\d+) +\[\[([^|]*)(|(.*))?\]\]/i,
							circ: /^circle +(\d+) +(\d+) +(\d+) +\[\[([^|]*)(|(.*))?\]\]/i,
							poly: /^poly +(.*?) +\[\[([^|]*)(|(.*))?\]\]/i
						};

						let results;
						if (results = detect.rect.exec(line)) {
							const area = areas.make("rect");
							area.coords = results.slice(1, 5);
							area.link = results[5];
							if (results[6]) area.title = results[6].substring(1);
						}
						else if (results = detect.circ.exec(line)) {
							const area = areas.make("circle");
							area.coords = results.slice(1, 4);
							area.link = results[4];
							if (results[5]) area.title = results[5].substring(1);
						}
						else if (results = detect.poly.exec(line)) {
							const area = areas.make("poly");
							area.coords = results[1].split(/\s+/);
							area.link = results[2];
							if (results[3]) area.title = results[3].substring(1);
						}
					}
					areas.update();
					this.hide();
				},
				show() {
					$('#imeImport').show();
					$('#imeImportShow').hide();
					$('#imeImportHide').show();
				},
				hide() {
					$('#imeImport').hide();
					$('#imeImportShow').show();
					$('#imeImportHide').hide();
				}
			}
		};

		if (document.getElementById('file'))
			init1();

		/*
			Initialization, part 1: Tries to find image and uses a XMLHttpRequest
			to download information about the image. When this is done (it's an
			asynchronous request) show a link to load the rest of ImageMapEdit
			using init2().
		*/
		function init1() {
			try {
				const divFile = document.getElementById('file');
				if (!divFile) throw 'divFile';
				const a = util.findHyperlink(divFile);
				if (!a) throw 'a';
				const img = a.firstChild;
				if (!img) throw 'img';
				const url =
					mw.config.get('wgScriptPath') +
					'/api.php?format=json&action=query&prop=imageinfo&' +
					'iiprop=size&titles=' + mw.config.get('wgPageName');
				$.get(url, data => {
					if (typeof data.query.pages != "undefined") {
						const imageProperties =
							data.query.pages[Object.keys(data.query.pages)[0]];
						const imageInfo = imageProperties.imageinfo;
						if (imageInfo) {
							ime.width = imageInfo[0].width;
							ime.height = imageInfo[0].height;
							ime.scale = img.width / ime.width;
							// Show 'show ImageMapEdit' button now
							$('<a>', { id: 'imeLink' })
								.css({ display: 'block' })
								.text('&langle;Start ImageMapEdit&rangle;')
								.click(util.std_handler(init2))
								.appendTo('#file');
						}
					}
				});
			}
			catch (e) {
				util.displayErr('ImageMapEdit initialization failed: "' + e + '" was missing');
			}
		}

		/*
			Initialization, part 2: Triggered by an external link. Does some moving
			around of the image in the logical structure of the page, then hides the
			link and finally puts the HTML code in place.
		*/
		function init2() {
			ime.trimUI();

			const divFile = document.getElementById('file'),
				tempNode = divFile.firstChild,
				a = util.findHyperlink(tempNode),
				img = a.firstChild,
				$img = $(img),
				divImeContainer = util.makeDiv('imeContainer');

			divImeContainer.style.position = 'relative';

			// Move image from within link to outside
			a.removeChild(img);

			divFile.insertBefore(divImeContainer, tempNode);
			divFile.removeChild(tempNode);
			// Fix for rtl wikis, thanks to hewiki user "קיפודנחש"
			divFile.style.direction = 'ltr';

			img.id = 'imeImg';
			img.style.border = 'none';
			img.oncontextmenu = function (e) {
				e.preventDefault();
				e.stopPropagation();
			};

			// Internet Explorer needs this differently
			divImeContainer.style.overflow =
				(typeof (navigator.userAgent) != 'undefined' &&
					navigator.userAgent.match('/MSIE/')) ?
					'none' : 'auto';
			divImeContainer.appendChild(img);

			ime.jcanvas = $('<canvas>')
				.css({
					position: 'absolute',
					width: $img.width() + 'px',
					height: $img.height() + 'px',
					border: 0,
					top: 0,
					left: 0
				})
				.attr({ width: $img.width(), height: $img.height() })
				.appendTo(divImeContainer);
			context = ime.jcanvas[0].getContext("2d");
			$.extend(context, {
				fillStyle: 'rgba(255,255,0,0.4)',
				strokeStyle: 'red',
				lineJoin: 'round',
				lineWidth: 1.5 / ime.scale
			}
			);
			context.scale(ime.scale, ime.scale);
			ime.jcanvas.click(mouse.fired.bind(mouse));
			function handler(e) {
				e.preventDefault();
				e.stopPropagation();
			}
			ime.jcanvas.click(handler);
			ime.jcanvas[0].oncontextmenu = img.oncontextmenu = handler;

			const divIme = util.makeDiv('ime');
			divFile.appendChild(divIme);

			// Hide the link now
			document.getElementById('imeLink').style.display = 'none';
			// Disable image context menu so right click can be used for events
			img.oncontextmenu = e => ((e.cancelBubble = true), false);

			$(divIme).html(ime.templateHtml);
			attachTemplate();
			util.translate();
		}

		function updateResult() {
			const arr = document.ime.imageDescriptionPos;
			let imageDescriptionPos = arr[0].value;
			for (let i = 1; i < arr.length; i++) {
				if (arr[i].checked) {
					imageDescriptionPos = arr[i].value;
					break;
				}
			}

			const results = Array().concat(
				['<imagemap>',
					mw.config.get('wgPageName') + '|' + document.ime.imageDescription.value,
					''],
				areas.map(area =>
					area.shape + ' ' + area.coords.join(' ') +
					' [[' + area.link + (area.title ? '|' + area.title : '') + ']]'),
				['',
					'desc ' + imageDescriptionPos,
					'</imagemap>']
			);

			const preResult = document.getElementById('imeResult');
			while (preResult.lastChild)
				preResult.removeChild(preResult.lastChild);

			for (const result of results) {
				preResult.appendChild(document.createTextNode(result));
				preResult.appendChild(document.createElement('br'));
			}
			area.updateSelection();
		}

		function updateInputs(fromAreas) {
			function updateShape(selectors, coords) {
				for (let index = 0; index < selectors.length; ++index)
					$(selectors[index]).val(coords && coords[index] || '');
			}

			function updatePolyInputs(coords) {
				$('#imePropsPolyCoords').text(coords.join(', '));
			}

			const area = areas.current(), coords = area.coords;
			switch (area.shape) {
				case 'rect':
					updateShape(['#ime_areaRectLeft', '#ime_areaRectTop', '#ime_areaRectRight', '#ime_areaRectBottom'], coords);
					break;
				case 'circle':
					updateShape(['#ime_areaCircleX', '#ime_areaCircleY', '#ime_areaCircleRadius'], coords);
					break;
				case 'poly':
					updatePolyInputs(coords);
					break;
			}
			$('#ime_areaLink').val(area.link || '');
			$('#ime_areaTitle').val(area.title || '');
		}

		function attachTemplate() {
			const clicks = {
				'.ime_t_rect': () => areas.make('rect'),
				'.ime_t_circle': () => areas.make('circle'),
				'.ime_t_poly': () => areas.make('poly'),
				'.ime_t_deletearea': areas.remove.bind(areas),
				'#imeImportShow': ime.imports.show.bind(ime.imports),
				'#imeImportHide': ime.imports.hide.bind(ime.imports),
				'.ime_t_import': ime.imports.make.bind(ime.imports),
				'.ime_t_deletecoordinates': () => {
					areas.current().coords = [];
					mouse.currentClicks = {};
					ime.store();
				}
			};
			for (const id in clicks) $(id).click(utils.std_handler(clicks[id]));
			const changes = {
				'#ime_areaselector': function (e) { areas.edit($(this).prop('selectedIndex')); },
				'.ime_saveonchange': ime.store.bind(ime),
				'.ime-updateresultsonchange': updateResult,
				'#ime_areaLink': function () { areas.current().link = $(this).val(); updateResult(); },
				'#ime_areaTitle': function () { areas.current().title = $(this).val(); updateResult(); }
			};
			for (const id in changes) $(id).change(changes[id]);
			areas.selection = $('#ime_areaselector');
			$('.ime-saveonchange').focusout(function () {
				const input = $(this);
				const ind = input.data('coord');
				const val = parseInt(input.val());
				const area = areas.current();
				const coords = area && area.coords;
				if (coords && typeof (ind) == 'number' && typeof (val) == 'number' && !isNaN(val)) {
					coords[ind] = val;
					mouse.currentClicks = {};
					areas.draw();
				}
			});
			mw.loader.using(['mediawiki.api', 'jquery.ui']).done(function () {
				$('#ime_areaLink').autocomplete({
					source(request, response) {
						new mw.Api().get({
							action: 'opensearch',
							search: request.term,
							namespace: 0,
							limit: 10
						}).done(data => {
							if (data && data.length > 1)
								response(data[1]);
						}); // done
					} // source
				}); // autocomplete
			}); // using
		}


		// this is the one-(very long)-line version of the template, since mw linger does not allow use multiline delimiter (ascii 96), not even in the comment... the formatted version in comment below.
		ime.templateHtml = '<form name="ime" action=""><fieldset style="margin:0.5ex;padding:0 1ex 1ex"><legend>ImageMapEdit</legend><fieldset style="float:left;margin:0 0.5ex 0.5ex;padding:0 1ex 1ex"><legend style="padding:0 0.5ex" class="ime_t_newarea">Create new area</legend><a style="padding:1px;background:white;color:darkblue" class="ime_t_rect">rect(angle)</a><br /><a style="padding:1px;background:white;color:darkblue" class="ime_t_circle">circle</a><br /><a style="padding:1px;background:white;color:darkblue" class="ime_t_poly">poly(gon)</a></fieldset><fieldset style="float:left;margin:0 0.5ex 0.5ex;padding:0 1ex 1ex"><legend style="padding:0 0.5ex" class="ime_t_editarea">Edit area</legend><select id="ime_areaselector" size="10" style="float:left;height:10em;margin:0.5ex;width:auto;min-width:18em;" ></select><div id="imeProps" style="float:left;margin:0.5ex;padding:0 1ex 1ex;display:none"><div style="float:left;margin:0.5ex;padding:0 1ex 1ex"><label for="ime_areaLink" class="ime_t_linktarget">Link target</label><br /><input id="ime_areaLink" name="areaLink" style="width:10em" class="ime-saveonchange" /><br /><label for="ime_areaTitle"><span class="ime_t_linktitle">Link title</span> (<span class="ime_t_optional">optional</span>)</label><br /><input id="ime_areaTitle" name="areaTitle" style="width:10em" class="ime-saveonchange" /></div><div id="imePropsRect" class="ime-prop ime-prop-rect" style="float:left;margin:0.5ex;padding:0 1ex 1ex;display:none"><label for="ime_areaRectLeft" class="ime_t_rectleft">First corner</label><br /><input id="ime_areaRectLeft" name="areaRectLeft" data-coord=0 class="ime-saveonchange" style="width:4em" /><input id="ime_areaRectTop" name="areaRectTop" data-coord=1 style="width:4em" class="ime-saveonchange" /><span class="ime_t_rectchoose1">Select with left mouse button</span><br/><label for="ime_areaRectRight" class="ime_t_rectright">Second corner</label><br /><input id="ime_areaRectRight" name="areaRectRight" data-coord=2 style="width:4em" class="ime-saveonchange" /><input id="ime_areaRectBottom" name="areaRectBottom" data-coord=3 style="width:4em" class="ime-saveonchange" /><span class="ime_t_rectchoose2">Select with right mouse button</span></div><div id="imePropsCircle" class="ime-prop ime-prop-circle" style="float:left;margin:0.5ex;padding:0 1ex 1ex;display:none"><label class="ime_t_position">Position</label><br /><input name="areaCircleX" id="ime_areaCircleX" class="ime-saveonchange" data-coord=0 style="width:4em" /><input name="areaCircleY" id="ime_areaCircleY" style="width:4em" data-coord=1 class="ime-saveonchange" /><span class="ime_t_circlechoose1">Select with left mouse button</span><br /><label for="ime_areaCircleRadius" class="ime_t_radius">Radius</label><br /><input id="ime_areaCircleRadius" name="areaCircleRadius" data-coord=2 style="width:4em" class="ime-saveonchange" /><span class="ime_t_circlechoose2">Select with right mouse button</span></div><div id="imePropsPoly" class="ime-prop ime-prop-poly" style="float:left;margin:0.5ex;padding:0 1ex 1ex;display:none"><label class="ime_t_coordinates">Coordinates</label><br /><p id="imePropsPolyCoords" style="font-size:0.8em;max-width:20em;"></p><a style="padding:1px;background:white;color:darkblue" class="ime_t_deletecoordinates">Delete all coordinates</a><br /><span class="ime_t_polychoose">Add new corner with left mouse button</span></div><div style="clear:both"></div><a style="padding:1px;background:white;color:darkblue" class="ime_t_deletearea">Delete selected area</a></div><div style="clear:both"></div></fieldset><div style="clear:both"></div><fieldset style="margin:0 0.5ex 0.5ex;padding:0 1ex 1ex"><legend class="ime_t_preferences">General preferences</legend><div style="float:left;margin-right:1em;"><label for="ime_imageDescription" class="ime_t_imagedescription">Image description</label><br /><input id="ime_imageDescription" name="imageDescription" class="ime-updateresultsonchange" /></div><div style="float:left"><label style="display:block" class="ime_t_infolinkposition">Position of information link</label><div style="float:left"><input type="radio" name="imageDescriptionPos" value="bottom-left" class="ime-updateresultsonchange" checked="checked" id="ime_imageDescriptionPos_bottomleft" /><label for="ime_imageDescriptionPos_bottomleft"><span class="ime_t_bottomleft">Bottom left</span> (<span class="ime_t_default">default</span>)</label></div><div style="float:left"><input type="radio" name="imageDescriptionPos" value="bottom-right" class="ime-updateresultsonchange" id="ime_imageDescriptionPos_bottomright" /><label for="ime_imageDescriptionPos_bottomright" class="ime_t_bottomright">Bottom right</label></div><div style="float:left"><input type="radio" name="imageDescriptionPos" value="top-left" class="ime-updateresultsonchange" id="ime_imageDescriptionPos_topleft" /><label for="ime_imageDescriptionPos_topleft" class="ime_t_topleft">Top left</label></div><div style="float:left"><input type="radio" name="imageDescriptionPos" value="top-right" class="ime-updateresultsonchange" id="ime_imageDescriptionPos_topright" /><label for="ime_imageDescriptionPos_topright" class="ime_t_topright">Top right</label></div><div style="float:left"><input type="radio" name="imageDescriptionPos" value="none" class="ime-updateresultsonchange" id="ime_imageDescriptionPos_none" /><label for="ime_imageDescriptionPos_none" class="ime_t_nolink">No link</label></div></div><div style="clear:both"></div></fieldset><fieldset style="margin:0.5ex;padding:0 1ex 1ex"><legend class="ime_t_importareas">Import areas from wikicode</legend><a style="padding:1px;background:white;color:darkblue" id="imeImportShow"><span class="ime_t_showtextbox">Show text box</span> &gt;</a><a style="padding:1px;background:white;color:darkblue;display:none" id="imeImportHide"><span class="ime_t_hidetextbox">Hide text box</span> &lt;</a><div id="imeImport" style="display:none"><textarea name="importText" style="width:100%;margin:0;height:10em;display:block"></textarea><a style="padding:1px;background:white;color:darkblue" class="ime_t_import">Import</a></div></fieldset><fieldset style="margin:0.5ex;padding:0 1ex 1ex"><legend class="ime_t_generatedwikicode">Generated wikicode</legend><div><code id="imeResult" style="display:block;line-height:1.2em"></code></div></fieldset></fieldset></form>';
	});
/*
<form name="ime" action="">
	<fieldset style="margin:0.5ex;padding:0 1ex 1ex">
		<legend>ImageMapEdit</legend>
		<fieldset style="float:left;margin:0 0.5ex 0.5ex;padding:0 1ex 1ex">
			<legend style="padding:0 0.5ex" class="ime_t_newarea">Create new area</legend>
			<a style="padding:1px;background:white;color:darkblue" class="ime_t_rect">rect(angle)</a>
			<br />
			<a style="padding:1px;background:white;color:darkblue" class="ime_t_circle">circle</a>

			<br />
			<a style="padding:1px;background:white;color:darkblue" class="ime_t_poly">poly(gon)</a>
		</fieldset>
		<fieldset style="float:left;margin:0 0.5ex 0.5ex;padding:0 1ex 1ex">
			<legend style="padding:0 0.5ex" class="ime_t_editarea">Edit area</legend>
			<select id="ime_areaselector" size="10" style="float:left;height:10em;margin:0.5ex;width:auto;min-width:18em;" ></select>

			<div id="imeProps" style="float:left;margin:0.5ex;padding:0 1ex 1ex;display:none">
				<div style="float:left;margin:0.5ex;padding:0 1ex 1ex">

						<label for="ime_areaLink" class="ime_t_linktarget">Link target</label>
						<br />
						<input id="ime_areaLink" name="areaLink" style="width:10em" class="ime-saveonchange" />
						<br />
						<label for="ime_areaTitle"><span class="ime_t_linktitle">Link title</span> (<span class="ime_t_optional">optional</span>)</label>
						<br />

						<input id="ime_areaTitle" name="areaTitle" style="width:10em" class="ime-saveonchange" />
				</div>
				<div id="imePropsRect" class="ime-prop ime-prop-rect" style="float:left;margin:0.5ex;padding:0 1ex 1ex;display:none">
					<label for="ime_areaRectLeft" class="ime_t_rectleft">First corner</label>
					<br />
					<input id="ime_areaRectLeft" name="areaRectLeft"  data-coord=0 class="ime-saveonchange" style="width:4em" />
					<input id="ime_areaRectTop" name="areaRectTop"  data-coord=1 style="width:4em" class="ime-saveonchange" />

					<span class="ime_t_rectchoose1">Select with left mouse button</span>
					<br/>
					<label for="ime_areaRectRight" class="ime_t_rectright">Second corner</label>
					<br />
					<input id="ime_areaRectRight" name="areaRectRight"  data-coord=2 style="width:4em" class="ime-saveonchange" />
					<input id="ime_areaRectBottom" name="areaRectBottom"  data-coord=3 style="width:4em" class="ime-saveonchange" />
					<span class="ime_t_rectchoose2">Select with right mouse button</span>

				</div>
				<div id="imePropsCircle" class="ime-prop ime-prop-circle" style="float:left;margin:0.5ex;padding:0 1ex 1ex;display:none">
					<label class="ime_t_position">Position</label>
					<br />
					<input name="areaCircleX" id="ime_areaCircleX" class="ime-saveonchange" data-coord=0 style="width:4em" />
					<input name="areaCircleY" id="ime_areaCircleY" style="width:4em"  data-coord=1 class="ime-saveonchange" />
					<span class="ime_t_circlechoose1">Select with left mouse button</span>
					<br />

					<label for="ime_areaCircleRadius" class="ime_t_radius">Radius</label>
					<br />
					<input id="ime_areaCircleRadius" name="areaCircleRadius" data-coord=2 style="width:4em" class="ime-saveonchange" />
					<span class="ime_t_circlechoose2">Select with right mouse button</span>
				</div>
				<div id="imePropsPoly" class="ime-prop ime-prop-poly" style="float:left;margin:0.5ex;padding:0 1ex 1ex;display:none">
					<label class="ime_t_coordinates">Coordinates</label>

					<br />
					<p id="imePropsPolyCoords" style="font-size:0.8em;max-width:20em;"></p>
					<a style="padding:1px;background:white;color:darkblue" class="ime_t_deletecoordinates">Delete all coordinates</a>
					<br />
					<span class="ime_t_polychoose">Add new corner with left mouse button</span>
				</div>
				<div style="clear:both"></div>
				<a style="padding:1px;background:white;color:darkblue" class="ime_t_deletearea">Delete selected area</a>

			</div>
			<div style="clear:both"></div>
		</fieldset>
		<div style="clear:both"></div>
		<fieldset style="margin:0 0.5ex 0.5ex;padding:0 1ex 1ex">
			<legend class="ime_t_preferences">General preferences</legend>
			<div style="float:left;margin-right:1em;">
				<label for="ime_imageDescription" class="ime_t_imagedescription">Image description</label>

				<br />
				<input id="ime_imageDescription" name="imageDescription" class="ime-updateresultsonchange" />
			</div>
			<div style="float:left">
				<label style="display:block" class="ime_t_infolinkposition">Position of information link</label>
				<div style="float:left">
					<input type="radio" name="imageDescriptionPos" value="bottom-left" class="ime-updateresultsonchange" checked="checked" id="ime_imageDescriptionPos_bottomleft" /><label for="ime_imageDescriptionPos_bottomleft"><span class="ime_t_bottomleft">Bottom left</span> (<span class="ime_t_default">default</span>)</label>

				</div>
				<div style="float:left">
					<input type="radio" name="imageDescriptionPos" value="bottom-right" class="ime-updateresultsonchange" id="ime_imageDescriptionPos_bottomright" /><label for="ime_imageDescriptionPos_bottomright" class="ime_t_bottomright">Bottom right</label>
				</div>
				<div style="float:left">
					<input type="radio" name="imageDescriptionPos" value="top-left" class="ime-updateresultsonchange" id="ime_imageDescriptionPos_topleft" /><label for="ime_imageDescriptionPos_topleft" class="ime_t_topleft">Top left</label>
				</div>
				<div style="float:left">

					<input type="radio" name="imageDescriptionPos" value="top-right" class="ime-updateresultsonchange" id="ime_imageDescriptionPos_topright" /><label for="ime_imageDescriptionPos_topright" class="ime_t_topright">Top right</label>
				</div>
				<div style="float:left">
					<input type="radio" name="imageDescriptionPos" value="none" class="ime-updateresultsonchange" id="ime_imageDescriptionPos_none" /><label for="ime_imageDescriptionPos_none" class="ime_t_nolink">No link</label>
				</div>
			</div>
			<div style="clear:both"></div>
		</fieldset>

		<fieldset style="margin:0.5ex;padding:0 1ex 1ex">
			<legend class="ime_t_importareas">Import areas from wikicode</legend>
			<a style="padding:1px;background:white;color:darkblue" id="imeImportShow"><span class="ime_t_showtextbox">Show text box</span> &gt;</a>
			<a style="padding:1px;background:white;color:darkblue;display:none" id="imeImportHide"><span class="ime_t_hidetextbox">Hide text box</span> &lt;</a>
			<div id="imeImport" style="display:none">
				<textarea name="importText" style="width:100%;margin:0;height:10em;display:block"></textarea>

				<a style="padding:1px;background:white;color:darkblue" class="ime_t_import">Import</a>
			</div>
		</fieldset>
		<fieldset style="margin:0.5ex;padding:0 1ex 1ex">
			<legend class="ime_t_generatedwikicode">Generated wikicode</legend>
			<div>
				<code id="imeResult" style="display:block;line-height:1.2em"></code>
			</div>

		</fieldset>
	</fieldset>
</form>
`;

});
*/
//</nowiki>