„Benutzer:Dapete/ImageMapEdit.js“ – Versionsunterschied
Erscheinungsbild
Inhalt gelöscht Inhalt hinzugefügt
Dapete (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
Dapete (Diskussion | Beiträge) auf den Toolserver verschoben |
||
Zeile 1: | Zeile 1: | ||
// ImageMapEdit wurde auf den Toolserver verschoben; folgende Zeile ist alles, was zum Einbinden nötig ist: |
|||
/* Constants */ |
|||
importScriptURI('http://toolserver.org/~dapete/ime/ime.js'); |
|||
// Append a number at the end of these URLs to ensure that, if changes to the fragment have |
|||
// been made, a reload is forced. This is important if this is used in a |
|||
// heavily cached environment (say, Wikipedia). |
|||
// Location of the HTML fragment containing the form code for ImageMapEdit. |
|||
var IME_HTMLFILE = wgScriptPath + '/index.php?title=Benutzer:Dapete/ImageMapEdit.js/template.html.js&action=raw&3'; |
|||
// Location of the XML file containing translations |
|||
var IME_TRANSLATEFILE = wgScriptPath + '/index.php?title=Benutzer:Dapete/ImageMapEdit.js/translations.xml.js&action=raw&3'; |
|||
// Scripts to create the circle and polygon images |
|||
var IME_CIRCLESCRIPT = 'http://toolserver.org/~dapete/ImageMapEdit/circle.php'; |
|||
var IME_POLYSCRIPT = 'http://toolserver.org/~dapete/ImageMapEdit/poly.php'; |
|||
// Error messages that cannot be localized in XML |
|||
var IME_ERROR_IMAGENOTFOUND = 'ImageMapEdit: Konnte Bild in der Seitenstruktur nicht finden.'; |
|||
var IME_ERROR_XMLHTTPREQUEST = 'ImageMapEdit: Browser unterstützt XMLHttpRequest nicht.'; |
|||
var IME_ERROR_LOADURL = 'ImageMapEdit: Konnte URL nicht laden:'; |
|||
/* |
|||
Copyright (c) 2007-2009 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 |
|||
*/ |
|||
/* |
|||
Global variables |
|||
*/ |
|||
var ime_areas = Array(); |
|||
var ime_currentlyEditing = -1; |
|||
var ime_width; |
|||
var ime_height; |
|||
var ime_scale; |
|||
/* |
|||
Start Inizialization if this is an image page and there actually is an image |
|||
*/ |
|||
// Add hook |
|||
addOnloadHook(ime_onload); |
|||
function ime_onload() { |
|||
// Determine whether we are on an image page. Namespace must be 6 and action view |
|||
if (wgNamespaceNumber==6 && wgAction=='view') { |
|||
// If we can a div with id file, we initialize |
|||
if (document.getElementById('file')) { |
|||
ime_init1(); |
|||
} |
|||
} |
|||
} |
|||
/* |
|||
Create a XMLHttpRequest object, trying differnet methods. Returns |
|||
false if no XMLHttpRequest implementation could be found. |
|||
*/ |
|||
function ime_xmlHttpRequest() { |
|||
if (window.XMLHttpRequest) { |
|||
return new XMLHttpRequest(); |
|||
} |
|||
if (window.ActiveXObject) { |
|||
try { |
|||
return new ActiveXObject('Microsoft.XMLHTTP'); |
|||
} |
|||
catch (e) { |
|||
try { |
|||
return new ActiveXObject('Msxml2.XMLHTTP'); |
|||
} |
|||
catch (e) { |
|||
// Do nothing |
|||
} |
|||
} |
|||
} |
|||
if (window.createRequest) { |
|||
return window.createRequest(); |
|||
} |
|||
return false; |
|||
} |
|||
/* |
|||
Parses the XML in a string, trying different methods. Returns false if |
|||
anything doesn't work, otherwise returns an XML document object. |
|||
This is necessary because XML data returned from wiki pages in MediaWiki |
|||
is not parsed as XML correctly, probably because of Content-type problems. |
|||
In contrast, XML returned by the API works perfectly... |
|||
*/ |
|||
function ime_xmlParseString(xmlString) { |
|||
if (document.implementation && document.implementation.createDocument) { |
|||
var parser = new DOMParser(); |
|||
return parser.parseFromString(xmlString,'text/xml'); |
|||
} |
|||
if (window.ActiveXObject) { |
|||
try { |
|||
var xmlDoc = new ActiveXObject('Microsoft.XMLDOM'); |
|||
xmlDoc.async = 'false'; |
|||
xmlDoc.loadXML(xmlString); |
|||
return xmlDoc; |
|||
} |
|||
catch (e) { |
|||
// Do nothing |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
/* |
|||
Create a new div element object with an id. |
|||
*/ |
|||
function ime_htmlNewDiv(id) { |
|||
var div = document.createElement('div'); |
|||
if (id) div.id = id; |
|||
return div; |
|||
} |
|||
/* |
|||
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 ime_init2(). |
|||
*/ |
|||
function ime_init1() { |
|||
var divFile = document.getElementById('file'); |
|||
if (!divFile) { |
|||
ime_error(IME_ERROR_IMAGENOTFOUND + ' (ime_init1,divFile=null)'); |
|||
return; |
|||
} |
|||
var a = ime_findATag(divFile); |
|||
if (!a) { |
|||
ime_error(IME_ERROR_IMAGENOTFOUND + ' (ime_init1,a=null)'); |
|||
return; |
|||
} |
|||
var img = a.firstChild; |
|||
if (!img) { |
|||
ime_error(IME_ERROR_IMAGENOTFOUND + ' (ime_init1,img=null)'); |
|||
return; |
|||
} |
|||
// Now try to use API to get real image parameters |
|||
var request = ime_xmlHttpRequest(); |
|||
// First time we tried to get a xmlHttpRequest, so if it fails here, it's |
|||
// not supported at all |
|||
if (!request) { |
|||
ime_error(IME_ERROR_XMLHTTPREQUEST); |
|||
return; |
|||
} |
|||
var url = wgScriptPath + '/api.php?format=xml&action=query&prop=imageinfo&iiprop=size&titles=' + wgPageName; |
|||
request.open('GET', url, true); |
|||
request.send(null); |
|||
request.onreadystatechange = function() { |
|||
if (request.readyState == 4) { |
|||
if (request.status == 200) { |
|||
// Get image data |
|||
var response = request.responseXML.documentElement; |
|||
var iiAttr = response.getElementsByTagName('ii')[0].attributes; |
|||
ime_width = iiAttr.getNamedItem('width').nodeValue; |
|||
ime_height = iiAttr.getNamedItem('height').nodeValue; |
|||
ime_scale = img.width/ime_width; |
|||
// Show 'show ImageMapEdit' button now |
|||
var a = document.createElement('a'); |
|||
a.id = 'imeLink'; |
|||
a.href = 'javascript:ime_init2()'; |
|||
a.style.display = 'block'; |
|||
a.appendChild(document.createTextNode('ImageMapEdit >')); |
|||
document.getElementById('file').appendChild(a); |
|||
return; |
|||
} |
|||
else { |
|||
ime_error (IME_ERROR_LOADURL + ' ' + url + ' (ime_init1,request.status=' + request.status + ').'); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
/* |
|||
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 loads some more HTML code and translation information |
|||
from external files (IME_HTMLFILE and IME_TRANSLATEFILE) using an |
|||
asynchronous XMLHttpRequest. |
|||
*/ |
|||
function ime_init2() { |
|||
// Remove UI that might interfere with this code |
|||
ime_removeOtherUIElements(); |
|||
var divFile = document.getElementById('file'); |
|||
var tempNode = divFile.firstChild; |
|||
var a = ime_findATag(tempNode); |
|||
var img = a.firstChild; |
|||
var divImeContainer = ime_htmlNewDiv('imeContainer'); |
|||
divImeContainer.style.position = 'relative'; |
|||
// Move image from within link to outside |
|||
a.removeChild(img); |
|||
divFile.insertBefore(divImeContainer,tempNode); |
|||
divFile.removeChild(tempNode); |
|||
img.id = 'imeImg'; |
|||
img.style.zIndex = 99; |
|||
img.style.border = 'none'; |
|||
img.style.opacity = '0.75'; |
|||
img.style.filter = 'alpha(opacity=75)'; // IE |
|||
// Internet Explorer needs this differently |
|||
if (typeof(navigator.userAgent) != 'undefined' && navigator.userAgent.match('/MSIE/')) { |
|||
divImeContainer.style.overflow = 'none'; |
|||
} |
|||
else { |
|||
divImeContainer.style.overflow = 'auto'; |
|||
} |
|||
var divImePreview = ime_htmlNewDiv('imePreview'); |
|||
divImePreview.style.position = 'absolute'; |
|||
divImePreview.style.top = '0'; |
|||
divImePreview.style.left = '0'; |
|||
divImePreview.style.width = img.width + 'px'; |
|||
divImePreview.style.height = img.height + 'px'; |
|||
divImePreview.zIndex = 0; |
|||
divImeContainer.appendChild(divImePreview); |
|||
divImeContainer.appendChild(img); |
|||
var divIme = ime_htmlNewDiv('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 = ime_eventDummy; |
|||
// Load form data with HTTP |
|||
var request = ime_xmlHttpRequest(); |
|||
if (!request) { |
|||
ime_error (IME_ERROR_LOADURL + ' ' + url + ' (ime_init2,request=null)'); |
|||
return; |
|||
} |
|||
request.open('GET', IME_HTMLFILE, true); |
|||
request.onreadystatechange = function() { |
|||
if (request.readyState == 4) { |
|||
if (request.status == 200) { |
|||
divIme.innerHTML = request.responseText; |
|||
// Another request for the XML file containing translations |
|||
var request2 = ime_xmlHttpRequest(); |
|||
if (!request) { |
|||
ime_error (IME_ERROR_LOADURL + ' ' + url + ' (ime_init2,request2=null)'); |
|||
return; |
|||
} |
|||
request2.open('GET', IME_TRANSLATEFILE, true); |
|||
request2.onreadystatechange = function() { |
|||
if (request2.readyState == 4) { |
|||
if (request2.status == 200) { |
|||
var response; |
|||
if (request2.responseXML) { |
|||
response = request2.responseXML.documentElement; |
|||
} |
|||
else { |
|||
// Stupid workaround of responseXML is empty - |
|||
// just parse the responseText again |
|||
response = ime_xmlParseString(request2.responseText).documentElement; |
|||
} |
|||
var languages = response.getElementsByTagName('language'); |
|||
// Use translation for the currently set language (MediaWiki supplies this in wgUserLanguage) |
|||
ime_translate(wgUserLanguage, languages); |
|||
} |
|||
else { |
|||
ime_error (IME_ERROR_LOADURL + ' ' + IME_TRANSLATEFILE + ' (ime_init2,request2.status=' + request2.status + ').'); |
|||
} |
|||
} |
|||
} |
|||
request2.send(null); |
|||
} |
|||
else { |
|||
ime_error (IME_ERROR_LOADURL + ' ' + IME_HTMLFILE + ' (ime_init2,request.status=' + request.status + ').'); |
|||
} |
|||
} |
|||
} |
|||
request.send(null); |
|||
} |
|||
/* |
|||
Translate the user interface to the specified language. |
|||
*/ |
|||
function ime_translate(languageCode, languages) { |
|||
var language = false; |
|||
// Try to find language information |
|||
for (var i=0; i<languages.length; i++) { |
|||
if (languages[i].attributes.getNamedItem('name').nodeValue == languageCode) { |
|||
language = languages[i]; |
|||
break; |
|||
} |
|||
} |
|||
// If a language has been found ... |
|||
if (language) { |
|||
// ... see if we need to inherit another language |
|||
if (language.attributes.getNamedItem('inherit')) { |
|||
// If we do, we call ourselves recursively to translate to that language first |
|||
ime_translate(language.attributes.getNamedItem('inherit').nodeValue, languages); |
|||
} |
|||
// ... get all the translations and replace the text in the HTML |
|||
var translations = language.getElementsByTagName('translation'); |
|||
for (var i=0; i<translations.length; i++) { |
|||
var translation = translations[i]; |
|||
var elements = ime_getElementsByClassName('ime_t_' + translation.attributes.getNamedItem('name').nodeValue); |
|||
if (elements.length > 0) { |
|||
var text = translation.firstChild.nodeValue; |
|||
for (var j=0; j<elements.length; j++) { |
|||
elements[j].innerHTML = text; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
/* |
|||
Finds all elements in the current document with the specified class. |
|||
*/ |
|||
function ime_getElementsByClassName(className) { |
|||
// Hopefully the browser supports this natively |
|||
if (document.getElementsByClassName) { |
|||
return document.getElementsByClassName(className); |
|||
} |
|||
// Otherwise use the function defined by MediaWiki |
|||
return getElementsByClassName(document,'*',className) |
|||
} |
|||
/* |
|||
Display an error message, either by putting it on the page or - if the |
|||
place to put it does not exist - by showing an alert box. |
|||
*/ |
|||
function ime_error(message) { |
|||
var divFile = document.getElementById('file'); |
|||
if (divFile) { |
|||
var pImeError = document.createElement('p'); |
|||
pImeError.style.color = 'darkred'; |
|||
pImeError.style.background = 'white'; |
|||
pImeError.style.border = '1px solid darkred'; |
|||
pImeError.style.padding = '1ex'; |
|||
pImeError.appendChild(document.createTextNode(message)); |
|||
var divIme = document.getElementById('ime'); |
|||
if (divIme) { |
|||
divIme.insertBefore(pImeError,divIme.firstChild); |
|||
} |
|||
else { |
|||
divFile.appendChild(pImeError); |
|||
} |
|||
} |
|||
else { |
|||
window.alert(message); |
|||
} |
|||
} |
|||
/* |
|||
Dummy function to intercept events |
|||
*/ |
|||
function ime_eventDummy(e) { |
|||
e.cancelBubble = true; |
|||
return false; |
|||
} |
|||
/* |
|||
Function to define an object containing rect(angle) coordinates. |
|||
*/ |
|||
function ime_RectCoord(x1,y1,x2,y2) { |
|||
this.left = x1; |
|||
this.top = y1; |
|||
this.right = x2; |
|||
this.bottom = y2; |
|||
} |
|||
/* |
|||
Function to define an object containing circle coordinates. |
|||
*/ |
|||
function ime_CircleCoord(x,y,r) { |
|||
this.x = x; |
|||
this.y = y; |
|||
this.radius = r; |
|||
} |
|||
/* |
|||
Function to define an object containing poly(gon) coordinates. |
|||
*/ |
|||
function ime_PolyCoord(x,y,r) { |
|||
this.points = Array(); |
|||
} |
|||
/* |
|||
Function to define an object storing info on a clickable area for the |
|||
imagemap. |
|||
*/ |
|||
function ime_Area(shape) { |
|||
if (shape=='rect') { |
|||
this.shape = 'rect'; |
|||
this.coords = new ime_RectCoord(0,0,0,0); |
|||
} |
|||
else if (shape=='circle') { |
|||
this.shape = 'circle'; |
|||
this.coords = new ime_CircleCoord(0,0,20); |
|||
} |
|||
else { |
|||
this.shape = 'poly'; |
|||
this.coords = new ime_PolyCoord(); |
|||
} |
|||
this.link = ''; |
|||
this.title = ''; |
|||
} |
|||
/* |
|||
Browser invariant function to get the event "behind" the object passed |
|||
to event handlers. |
|||
*/ |
|||
function ime_getEvent(e) { |
|||
if (e) { |
|||
return e; |
|||
} |
|||
else { |
|||
return window.event; |
|||
} |
|||
} |
|||
function ime_eventGetX(e) { |
|||
if (typeof(e.layerX)!='undefined') { |
|||
return Math.round(e.layerX / ime_scale); |
|||
} |
|||
if (typeof(e.offsetX)!='undefined') { |
|||
return Math.round(e.offsetX / ime_scale); |
|||
} |
|||
else { |
|||
return Math.round(e.x / ime_scale); |
|||
} |
|||
} |
|||
function ime_eventGetY(e) { |
|||
if (typeof(e.layerY)!='undefined') { |
|||
return Math.round(e.layerY / ime_scale); |
|||
} |
|||
if (typeof(e.offsetY)!='undefined') { |
|||
return Math.round(e.offsetY / ime_scale); |
|||
} |
|||
else { |
|||
return Math.round(e.y / ime_scale); |
|||
} |
|||
} |
|||
function ime_eventGetButton(e) { |
|||
if (typeof(e.which)!='undefined') { |
|||
return e.which; |
|||
} |
|||
else { |
|||
return e.button; |
|||
} |
|||
} |
|||
function ime_mouseEventClear() { |
|||
var img = document.getElementById('imeImg'); |
|||
img.onmousedown = null; |
|||
img.style.cursor = ''; |
|||
} |
|||
function ime_mouseEventSet(func) { |
|||
var img = document.getElementById('imeImg'); |
|||
img.onmousedown = func; |
|||
img.style.cursor = 'crosshair'; |
|||
} |
|||
function ime_eventRect(e) { |
|||
e = ime_getEvent(e); |
|||
var button = ime_eventGetButton(e); |
|||
if (button==1) { |
|||
document.ime.areaRectLeft.value = ime_eventGetX(e); |
|||
document.ime.areaRectTop.value = ime_eventGetY(e); |
|||
} |
|||
else if (button==2 || button==3) { |
|||
document.ime.areaRectRight.value = ime_eventGetX(e); |
|||
document.ime.areaRectBottom.value = ime_eventGetY(e); |
|||
} |
|||
ime_saveArea(); |
|||
return false; |
|||
} |
|||
function ime_eventCircle(e) { |
|||
e = ime_getEvent(e); |
|||
var button = ime_eventGetButton(e); |
|||
if (button==1) { |
|||
document.ime.areaCircleX.value = ime_eventGetX(e); |
|||
document.ime.areaCircleY.value = ime_eventGetY(e); |
|||
} |
|||
else if (button==2 || button==3) { |
|||
var a = (ime_eventGetX(e) - parseInt(document.ime.areaCircleX.value)); |
|||
var b = (ime_eventGetY(e) - parseInt(document.ime.areaCircleY.value)); |
|||
document.ime.areaCircleRadius.value = Math.round(Math.sqrt(a*a + b*b)); |
|||
} |
|||
ime_saveArea(); |
|||
return false; |
|||
} |
|||
function ime_eventPoly(e) { |
|||
e = ime_getEvent(e); |
|||
var button = ime_eventGetButton(e); |
|||
if (button==1) { |
|||
area = ime_areas[ime_currentlyEditing]; |
|||
area.coords.points.push(ime_eventGetX(e)); |
|||
area.coords.points.push(ime_eventGetY(e)); |
|||
ime_saveArea(); |
|||
} |
|||
return false; |
|||
} |
|||
function ime_newArea(shape) { |
|||
var area = new ime_Area(shape); |
|||
area.shape = shape; |
|||
ime_areas.push(area); |
|||
ime_currentlyEditing = ime_areas.length-1; |
|||
ime_updateAreas(); |
|||
ime_editArea(ime_currentlyEditing); |
|||
} |
|||
function ime_updateAreas() { |
|||
ime_updateSelectArea(); |
|||
ime_updateMap(); |
|||
ime_updateResult(); |
|||
} |
|||
function ime_updateResult() { |
|||
var arr = document.ime.imageDescriptionPos; |
|||
var imageDescriptionPos = arr[0].value; |
|||
for (var i=1; i<arr.length; i++) { |
|||
if (arr[i].checked) { |
|||
imageDescriptionPos = arr[i].value; |
|||
break; |
|||
} |
|||
} |
|||
var result = Array(); |
|||
result.push('<imagemap>'); |
|||
result.push(wgPageName + '|' + document.ime.imageDescription.value); |
|||
result.push(''); |
|||
for (var i=0; i<ime_areas.length; i++) { |
|||
var coords = ime_areas[i].coords; |
|||
var s = ''; |
|||
if (ime_areas[i].shape=='rect') { |
|||
s = coords.left + ' ' + coords.top + ' ' + coords.right + ' ' + coords.bottom; |
|||
} |
|||
else if (ime_areas[i].shape=='circle') { |
|||
s = coords.x + ' ' + coords.y + ' ' + coords.radius; |
|||
} |
|||
else if (ime_areas[i].shape=='poly') { |
|||
s = coords.points.join(' '); |
|||
} |
|||
result.push(ime_areas[i].shape + ' ' + s + ' [[' + ime_areas[i].link + (ime_areas[i].title ? '|' + ime_areas[i].title : '') + ']]'); |
|||
} |
|||
result.push(''); |
|||
result.push('desc ' + imageDescriptionPos); |
|||
result.push('</imagemap>'); |
|||
var preResult = document.getElementById('imeResult'); |
|||
while (preResult.lastChild) { |
|||
preResult.removeChild(preResult.lastChild); |
|||
} |
|||
for (var i=0; i<result.length; i++) { |
|||
preResult.appendChild(document.createTextNode(result[i])); |
|||
preResult.appendChild(document.createElement('br')); |
|||
} |
|||
} |
|||
function ime_updateMap() { |
|||
var preview = document.getElementById('imePreview'); |
|||
var img = document.getElementById('imeImg'); |
|||
// Remove areas from map which are out of range |
|||
for (var i=0; i<preview.childNodes.length; i++) { |
|||
var child = preview.childNodes[i]; |
|||
var id = parseInt(child.id.substring(10)); |
|||
if (id>=ime_areas.length) { |
|||
preview.removeChild(child); |
|||
i--; |
|||
} |
|||
} |
|||
for (var i=0; i<ime_areas.length; i++) { |
|||
// Get existing DIV |
|||
var area = ime_areas[i]; |
|||
var div = document.getElementById('imePreview' + i); |
|||
// If it does not exist exists, create a new one and set style |
|||
if (!div) { |
|||
var div = ime_htmlNewDiv('imePreview' + i) |
|||
preview.appendChild(div); |
|||
div.style.zIndex = 0; |
|||
div.style.position = 'absolute'; |
|||
div.style.opacity = 0.5; |
|||
div.style.filter = 'alpha(opacity=50)'; |
|||
} |
|||
var coords = area.coords; |
|||
if (area.shape == 'rect') { |
|||
div.className = 'previewRect'; |
|||
// Only if valid coordinates were given, draw |
|||
if (coords.left<coords.right && coords.top<coords.bottom) { |
|||
div.style.left = Math.round(ime_scale * coords.left) + 'px'; |
|||
div.style.top = Math.round(ime_scale * coords.top) + 'px'; |
|||
div.style.width = (Math.round(ime_scale * coords.right) - Math.round(ime_scale * coords.left)) + 'px'; |
|||
div.style.height = (Math.round(ime_scale * coords.bottom) - Math.round(ime_scale * coords.top)) + 'px'; |
|||
} |
|||
else { |
|||
div.style.left = '0'; |
|||
div.style.top = '0'; |
|||
div.style.width = '0'; |
|||
div.style.height = '0'; |
|||
} |
|||
} |
|||
else if (area.shape == 'circle') { |
|||
div.className = 'previewCircle'; |
|||
div.style.backgroundRepeat = 'no-repeat'; |
|||
var left = Math.round(ime_scale * coords.x) - Math.round(ime_scale * coords.radius); |
|||
var top = Math.round(ime_scale * coords.y) - Math.round(ime_scale * coords.radius); |
|||
var size = Math.round(ime_scale * coords.radius * 2) + 1; |
|||
div.style.left = left + 'px'; |
|||
div.style.top = top + 'px'; |
|||
if (left + size > img.width) { |
|||
div.style.width = (img.width - left) + 'px'; |
|||
} |
|||
else { |
|||
div.style.width = size + 'px'; |
|||
} |
|||
if (top + size > img.height) { |
|||
div.style.height = (img.height - top) + 'px'; |
|||
} |
|||
else { |
|||
div.style.height = size + 'px'; |
|||
} |
|||
} |
|||
else if (area.shape == 'poly') { |
|||
// Determine maximum coordinates (this is how big the image is) |
|||
div.className = 'previewPoly'; |
|||
div.style.backgroundRepeat = 'no-repeat'; |
|||
var points = coords.points; |
|||
var minX=0; var maxX=0; var minY=0; var maxY=0; |
|||
if (points.length>0) { |
|||
minX = points[0]; |
|||
maxX = points[0]; |
|||
minY = points[1]; |
|||
maxY = points[1]; |
|||
for (var j=2; j<points.length; j+=2) { |
|||
var x = points[j]; |
|||
var y = points[j+1]; |
|||
if (x<minX) minX = x; |
|||
if (x>maxX) maxX = x; |
|||
if (y<minY) minY = y; |
|||
if (y>maxY) maxY = y; |
|||
} |
|||
} |
|||
div.style.left = Math.round(ime_scale * minX) + 'px'; |
|||
div.style.top = Math.round(ime_scale * minY) + 'px'; |
|||
div.style.width = (Math.round(ime_scale * maxX) - Math.round(ime_scale * minX)) + 'px'; |
|||
div.style.height = (Math.round(ime_scale * maxY) - Math.round(ime_scale * minY)) + 'px'; |
|||
} |
|||
} |
|||
ime_highlightMap(); |
|||
} |
|||
function ime_highlightMapCircle(div,radius,highlight) { |
|||
var background = "url('" + IME_CIRCLESCRIPT + '?' + (highlight ? 'active=1&' : '') + 'radius=' + Math.round(ime_scale * radius) + "') no-repeat"; |
|||
if (div.style.background != background) { |
|||
div.style.background = background; |
|||
} |
|||
} |
|||
function ime_highlightMapPoly(div,points,highlight) { |
|||
var minX=0; var minY=0; |
|||
if (points.length>0) { |
|||
minX = points[0]; |
|||
minY = points[1]; |
|||
for (var j=2; j<points.length; j+=2) { |
|||
var x = points[j]; |
|||
var y = points[j+1]; |
|||
if (x<minX) minX = x; |
|||
if (y<minY) minY = y; |
|||
} |
|||
} |
|||
var convpoints = Array(); |
|||
for(var j=0; j<points.length; j+=2) { |
|||
convpoints[j] = Math.round(ime_scale * points[j]) - Math.round(ime_scale * minX); |
|||
convpoints[j+1] = Math.round(ime_scale * points[j+1]) - Math.round(ime_scale * minY); |
|||
} |
|||
var background = "url('" + IME_POLYSCRIPT + '?' + (highlight ? 'active=1&' : '') + 'coords=' + convpoints.join("|") + "') no-repeat"; |
|||
if (div.style.background != background) { |
|||
div.style.background = background; |
|||
} |
|||
} |
|||
function ime_highlightMap() { |
|||
for (var i=0; i<ime_areas.length; i++) { |
|||
var div = document.getElementById('imePreview' + i); |
|||
var area = ime_areas[i]; |
|||
if (div && area) { |
|||
if (area.shape == 'rect') { |
|||
var backgroundColor = (i==ime_currentlyEditing) ? 'red' : 'black'; |
|||
if (div.style.backgroundColor != backgroundColor) div.style.backgroundColor = backgroundColor; |
|||
} |
|||
else if (area.shape == 'circle') { |
|||
ime_highlightMapCircle(div,area.coords.radius,(i==ime_currentlyEditing)); |
|||
} |
|||
else if (area.shape == 'poly') { |
|||
ime_highlightMapPoly(div,area.coords.points,(i==ime_currentlyEditing)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
function ime_updateSelectArea() { |
|||
var selectArea = document.ime.area; |
|||
while (selectArea.childNodes.length>0) { |
|||
selectArea.removeChild(selectArea.lastChild); |
|||
} |
|||
for (var i=0; i<ime_areas.length; i++) { |
|||
var option = document.createElement('option'); |
|||
var area = ime_areas[i]; |
|||
option.value = i; |
|||
while (option.childNodes.length>0) { |
|||
option.removeChild(option.lastChild); |
|||
} |
|||
var text = (area.title ? area.title : area.link) + ' [' + area.shape + ']'; |
|||
option.appendChild(document.createTextNode(text)); |
|||
if (i == ime_currentlyEditing) { |
|||
option.selected = 'selected'; |
|||
} |
|||
selectArea.appendChild(option); |
|||
} |
|||
} |
|||
function ime_editArea(index) { |
|||
document.getElementById('imeProps').style.display = 'none'; |
|||
var area = ime_areas[index]; |
|||
if (area) { |
|||
ime_currentlyEditing = index; |
|||
document.getElementById('imeProps').style.display = ''; |
|||
document.getElementById('imePropsRect').style.display = 'none'; |
|||
document.getElementById('imePropsCircle').style.display = 'none'; |
|||
document.getElementById('imePropsPoly').style.display= 'none'; |
|||
ime_mouseEventClear(); |
|||
if (area.shape == 'rect') { |
|||
document.getElementById('imePropsRect').style.display = ''; |
|||
ime_mouseEventSet(ime_eventRect); |
|||
} |
|||
else if (area.shape == 'circle') { |
|||
document.getElementById('imePropsCircle').style.display = ''; |
|||
ime_mouseEventSet(ime_eventCircle); |
|||
} |
|||
else if (area.shape == 'poly') { |
|||
document.getElementById('imePropsPoly').style.display = ''; |
|||
ime_mouseEventSet(ime_eventPoly); |
|||
} |
|||
document.ime.areaLink.value = area.link; |
|||
document.ime.areaTitle.value = area.title; |
|||
var coords = area.coords; |
|||
if (area.shape == 'rect') { |
|||
document.ime.areaRectLeft.value = coords.left; |
|||
document.ime.areaRectTop.value = coords.top; |
|||
document.ime.areaRectRight.value = coords.right; |
|||
document.ime.areaRectBottom.value = coords.bottom; |
|||
} |
|||
else if (area.shape == 'circle') { |
|||
document.ime.areaCircleX.value = coords.x; |
|||
document.ime.areaCircleY.value = coords.y; |
|||
document.ime.areaCircleRadius.value = coords.radius; |
|||
} |
|||
else if (area.shape == 'poly') { |
|||
var propsPolyCoords = document.getElementById('imePropsPolyCoords'); |
|||
if (propsPolyCoords.childNodes.length > 0) propsPolyCoords.removeChild(propsPolyCoords.lastChild); |
|||
propsPolyCoords.appendChild(document.createTextNode(area.coords.points.join(", "))); |
|||
} |
|||
ime_highlightMap(); |
|||
} |
|||
} |
|||
function ime_deletePolyCoords() { |
|||
ime_areas[ime_currentlyEditing].coords.points = Array(); |
|||
ime_saveArea(); |
|||
} |
|||
function ime_saveArea() { |
|||
var area = ime_areas[ime_currentlyEditing]; |
|||
area.link = document.ime.areaLink.value; |
|||
area.title = document.ime.areaTitle.value; |
|||
var coords = area.coords; |
|||
if (area.shape=='rect') { |
|||
coords.left = parseInt(document.ime.areaRectLeft.value); |
|||
coords.top = parseInt(document.ime.areaRectTop.value); |
|||
coords.right = parseInt(document.ime.areaRectRight.value); |
|||
coords.bottom = parseInt(document.ime.areaRectBottom.value); |
|||
} |
|||
else if (area.shape=='circle') { |
|||
if (parseInt(document.ime.areaCircleRadius.value) < 0) document.ime.areaCircleRadius.value = 0; |
|||
coords.x = parseInt(document.ime.areaCircleX.value); |
|||
coords.y = parseInt(document.ime.areaCircleY.value); |
|||
coords.radius = parseInt(document.ime.areaCircleRadius.value); |
|||
} |
|||
else if (area.shape == 'poly') { |
|||
var propsPolyCoords = document.getElementById('imePropsPolyCoords'); |
|||
if (propsPolyCoords.childNodes.length > 0) propsPolyCoords.removeChild(propsPolyCoords.lastChild); |
|||
propsPolyCoords.appendChild(document.createTextNode(coords.points.join(", "))); |
|||
} |
|||
ime_updateAreas(); |
|||
} |
|||
function ime_deleteArea() { |
|||
ime_mouseEventClear(); |
|||
// Remove element from ime_areas array |
|||
ime_areas.splice(ime_currentlyEditing,1); |
|||
// Remove preview div of the deleted area |
|||
var div = document.getElementById('imePreview' + ime_currentlyEditing); |
|||
if (div) { |
|||
div.parentNode.removeChild(div); |
|||
} |
|||
// Move ids of preview divs to fill the hole |
|||
for (var i=ime_currentlyEditing+1; i<ime_areas.length; i++) { |
|||
div = document.getElementById('imePreview' + i); |
|||
if (div) { |
|||
div.id = 'imePreview' + (i-1); |
|||
} |
|||
} |
|||
// If we deleted the last area, correct currently editing |
|||
if (ime_currentlyEditing>=ime_areas.length) { |
|||
ime_currentlyEditing = ime_areas.length-1; |
|||
} |
|||
ime_updateAreas(); |
|||
ime_editArea(ime_currentlyEditing); |
|||
} |
|||
function ime_importLines() { |
|||
var text = document.ime.importText.value; |
|||
var lines = text.split("\n"); |
|||
for (var i=0; i<lines.length; i++) { |
|||
var rectMatch = /rect +(\d+) +(\d+) +(\d+) +(\d+) +\[\[([^|]*)(|(.*))?\]\]/i; |
|||
var circleMatch = /circle +(\d+) +(\d+) +(\d+) +\[\[([^|]*)(|(.*))?\]\]/i; |
|||
var polyMatch = /poly +(.*?) +\[\[([^|]*)(|(.*))?\]\]/i; |
|||
var line = lines[i]; |
|||
if (rectMatch.test(line)) { |
|||
var results = rectMatch.exec(line); |
|||
var area = new ime_Area("rect"); |
|||
area.coords.left = parseInt(results[1]); |
|||
area.coords.top = parseInt(results[2]); |
|||
area.coords.right = parseInt(results[3]); |
|||
area.coords.bottom = parseInt(results[4]); |
|||
area.link = results[5]; |
|||
if (results[6]) area.title = results[6].substring(1); |
|||
ime_areas.push(area); |
|||
} |
|||
else if (circleMatch.test(line)) { |
|||
var results = circleMatch.exec(line); |
|||
var area = new ime_Area("circle"); |
|||
area.coords.x = parseInt(results[1]); |
|||
area.coords.y = parseInt(results[2]); |
|||
area.coords.radius = parseInt(results[3]); |
|||
area.link = results[4]; |
|||
if (results[5]) area.title = results[5].substring(1); |
|||
ime_areas.push(area); |
|||
} |
|||
else if (polyMatch.test(line)) { |
|||
var results = polyMatch.exec(line); |
|||
var area = new ime_Area("poly"); |
|||
area.coords.points = results[1].replace(/ +/," ").split(" "); |
|||
for (var j=0; j<area.coords.points.length; j++) { |
|||
area.coords.points[j] = parseInt(area.coords.points[j]); |
|||
} |
|||
area.link = results[2]; |
|||
if (results[3]) area.title = results[3].substring(1); |
|||
ime_areas.push(area); |
|||
} |
|||
} |
|||
ime_updateAreas(); |
|||
ime_hideImport(); |
|||
} |
|||
function ime_showImport() { |
|||
document.getElementById('imeImport').style.display = ''; |
|||
document.getElementById('imeImportShow').style.display = 'none'; |
|||
document.getElementById('imeImportHide').style.display = ''; |
|||
} |
|||
function ime_hideImport() { |
|||
document.getElementById('imeImport').style.display = 'none'; |
|||
document.getElementById('imeImportShow').style.display = ''; |
|||
document.getElementById('imeImportHide').style.display = 'none'; |
|||
} |
|||
/* |
|||
Remove all UI elements that might interfere with ImageMapEdit. |
|||
*/ |
|||
function ime_removeOtherUIElements() { |
|||
// Remove all UI elements of the 'annotations' feature used on Wikimedia |
|||
// Commons. |
|||
var addButton = document.getElementById('ImageAnnotationAddButton'); |
|||
if (addButton) { |
|||
var whatToDelete = addButton.parentNode.parentNode; |
|||
var whereToDelete = whatToDelete.parentNode; |
|||
whereToDelete.removeChild(whatToDelete); |
|||
} |
|||
} |
|||
/* |
|||
Try to find an <a> tag within the specified HTML document node. |
|||
*/ |
|||
function ime_findATag(node) { |
|||
// We just look at the first child until there is none or it is an <a> tag |
|||
var a = node; |
|||
while (a != null && a.nodeName.toUpperCase() != 'A') { |
|||
a = a.firstChild; |
|||
} |
|||
return a; |
|||
} |