User:Codehydro/Auto CSS image crop/functions.js

function automake { if(!imgs[0]) return; at = ""; autotemp.style.height = ""; autotemp.style.height = autotemp.scrollHeight + 3 + "px"; }

function plusminus1pct(e) { if((k = (e ? e : event).keyCode) == 38 || k == 40) { (ae = document.activeElement).value = ae.value + Math.max(1, Math.round(lastWidth / 100)) * (k == 38 ? 1 : (k == 40 ? -1 : 0));		if((ei = Array.prototype.indexOf.call(fe, ae)) === 2 || ei === 3) updateCrop; else if(ei > 3) scrollSet; } }

function updateCrop { if(lastWidth && lastWidth == fe[1].value || imgs[0] && imgs[0].max < fe[1].value) { if(((rs = fe[ei = 2].value.split(">")).length == 2 || (rs = fe[ei = 3].value.split(">")).length == 2) && rs[1]) { rs = (rs[0] || (ei == 2 ? fe[1].value * lastWidthPct : lastHeight * lastHeightPct)) / rs[1] || 1; for(i = 5; i > 0; i--) fe[i].value = Math.round((i == ei ? (i == 2 ? fe[1].value * lastWidthPct : lastHeight * lastHeightPct) : fe[i].value) / rs); pc.onscroll = ""; updateImage; } else { if(!fe[2].value) fe[2].value = Math.round(lastWidth * lastWidthPct); if(!fe[3].value) fe[3].value = Math.round(lastHeight * lastHeightPct); fe[2].value = Math.max(0, Math.min(parseInt(fe[2].value), lastWidth)); fe[3].value = Math.max(0, Math.min(parseInt(fe[3].value), lastHeight)); pc.style.width = (parseInt(fe[2].value) + scrBar) + "px"; pc.style.height = (parseInt(fe[3].value) + scrBar) + "px"; scrollSet; drawClick; pc.onscroll = scrollFind; }		cform.className = ""; } }

function lastPct { if(lastWidth && lastWidth == fe[1].value) { lastTopPct = pc.scrollTop / lastHeight; lastLeftPct = pc.scrollLeft / lastWidth; lastWidthPct = fe[2].value / lastWidth; lastHeightPct = fe[3].value / lastHeight; sizeinfo.innerHTML = "Image data: " + Math.round(size / 102.4) / 10 + " KB | Non-visible overhead: " + Math.round((nvPct = 1 - lastWidthPct * lastHeightPct) * 100) + "%, ~ " + Math.round((nonvis = size * (nvPct)) / 102.4) / 10 + " KB"; if(mainKB && nonvis > mainKB * (big = 4)) { alert("Uploading a cropped image could reduce data by about " + Math.round(nonvis / 102.4) / 10 + "kB versus using this template. I am programmed to suggest this or a reduction in bSize when non-visible data is over " + Math.round(mainKB * big / 102.4) / 10 + "kB = " + big + "x the HTML data of '/wiki/Main Page' as of " + loadtime); mainKB = 0; }	}	automake; }

function scrollFind { if(lastWidth && lastWidth == fe[1].value) { pc.scrollTop = Math.max(0, Math.min(lastHeight - fe[3].value, pc.scrollTop)); pc.scrollLeft = Math.max(0, Math.min(lastWidth - fe[2].value, pc.scrollLeft)); pc.scrollTop = fe[4].value = Math.round(pc.scrollTop); pc.scrollLeft = fe[5].value = Math.round(pc.scrollLeft); lastPct; }	drawClick; }

function scrollSet { if(lastWidth && lastWidth == fe[1].value) { fe[4].value = Math.max(0, Math.min(lastHeight - fe[3].value, parseInt(fe[4].value))); fe[5].value = Math.max(0, Math.min(lastWidth - fe[2].value, parseInt(fe[5].value))); pc.scrollTop = fe[4].value; pc.scrollLeft = fe[5].value; lastPct; } }

function copyCrop { i = 0; if(lastClick[1]) while(i < 4 && mc[i].innerHTML == fe[i++ +2].value); if(lastFile && i < 4 && (fe[4].value || fe[5].value) > 0 && confirm("Draw lines around current visible area on next image? (Adds 2 points to click history; set with '" + cb1.innerText + "' on form.)")) return(lastClick[0] ? [] : lastClick).unshift([fe[5].value / lastWidth, fe[4].value / lastHeight], [(fe[5].value + fe[2].value) / lastWidth, (fe[4].value + fe[3].value) / lastHeight]); return; }

function updateImage { if(fe[6].getAttribute("readonly")) { setTimeout(updateImage, 99); return; }	if(lastFile && imgs[0]) lastFile = imgs[0].alt.replace("File:", ""); fe[0].value = fe[0].value.replace("File:", "").trim; if(!~fe[1].value.indexOf("max")) fe[1].value = parseInt(fe[1].value) || lastWidth; else if(imgs[0]) fe[1].value = imgs[0].max; if(fe[0].value && fe[1].value && (lastFile != fe[0].value || lastWidth != fe[1].value)) { if((isSame = lastFile == fe[0].value)) { fe[2].value = Math.round(fe[1].value * lastWidthPct); fe[3].value = Math.round((nh = (fe[1].value * lastHeight / lastWidth)) * lastHeightPct); fe[4].value = Math.round(nh * lastTopPct); fe[5].value = Math.round(fe[1].value * lastLeftPct); if(lastClick[0]) drawClick; } else { if(window.imp2 && imp2[0] != fe[0].value) others = []; load = new XMLHttpRequest; load.open('GET', '/wiki/File:' + fe[0].value, false); load.send; (ajx = document.createElement('div')).innerHTML = load.responseText.replace(/( src\=)/g, " srcurl="); for(i = (imgtag = ajx.getElementsByTagName("img")).length - 1; ~i; i--) if(imgtag[i].alt.indexOf("File:")) imgtag[i].parentNode.removeChild(imgtag[i]); imgtag = ajx.getElementsByTagName("img"); if(imgtag[0]) { copyCrop; imgs.unshift(imgtag[0]); } else { fe[0].value = (iv = "INVALID: ") + fe[0].value.replace(iv, ''); fe[0].onclick = function { fe[0].value = fe[0].value.replace(iv, fe[0].onclick = ''); };				return; }		}		imgs[0].max = imgs[0].getAttribute("data-file-width"); if(~fe[1].value.indexOf("max")) fe[1].value = imgs[0].max; if((wd = imgs[0].max - fe[1].value) < 0) { alert((isSame ? "Last valid crop restored." : "bSize set to max allowed.") + " Wiki servers will not process bSizes greater than the original image width" + (isSame ? " (" + imgs[0].max + "px). Type 'max' in bSize field to set." : ""));			if(isSame) { fe[2].value += ">" + Math.round(lastWidth * lastWidthPct); return updateCrop; }			fe[1].value = imgs[0].max; wd = 0; }		srcurl = imgs[0].getAttribute("srcurl").replace(RegExp(imgs[0].width + "(?=px)"), fe[1].value); if(!wd) srcurl = srcurl.replace(RegExp("/(thumb|" + fe[1].value + "[\\w\\W]+)", "g"), ""); else if(srcurl.indexOf("thumb") < 0) srcurl = srcurl.replace(RegExp("(./../)(?=" + (fn = imgs[0].alt.replace("File:", "").replace(/ /g, "_")) + ")"), "thumb/$1") + "/" + fe[1].value + "px-" + fn; if(~(ua = window.navigator.userAgent).indexOf("MSIE ") && ua.substr(ua.indexOf("MSIE ") + 5, 2) < 10) { (load = new XDomainRequest).open('GET', srcurl); load.send; load.onload = function { size = load.responseText.replace(/[\u0000-\u007F]/g, 9).replace(/[\u0080-\u07ff]/g, 99).replace(/[\u0800-\uffd7]/g, 999).length - (load.responseText.substr(1, 3) == "PNG" ? 8 : 4); };		} else { load.open('HEAD', srcurl, false); load.send; size = load.getResponseHeader("content-length"); }		cform.className = "hide"; imgcrop.src = srcurl; } else setTimeout(updateCrop, 9); }

function cImport { if(!fe[6].value || fe[6].getAttribute("readonly")) return; impSlow = false; if(!others[0] || confirm("The following will be discarded unless you cancel:\n " + others[0][0] + autotemp.innerHTML.split(others[0][0])[1].slice(0, -2).replace(/<[Bb][Rr]>/g, "").replace(/\r?\n?\| ?/g, "\n "))) { imp = fe[6].value.split("|"); (imp2 = []).count = 0; o2 = others; others = []; trimReg = /(^[ \t\r\n]+|(px)?[} \t\r\n]+$)/g; for(i = 1; imp[i]; i++) { params = imp[i].split("="); if((pli = labels.indexOf(params[0].trim)) >= 0) { imp2.count++; imp2[pli] = pli > 0 ? parseInt(params[1]) : params[1].replace(trimReg, ""); } else if(params.length == 2) { (ot = []).push(params[0].replace(trimReg, "")); ot.push(params[1].replace(trimReg, "")); others.push(ot); }		}		if(imp2.count == labels.length) { fe[6].value = "Import successful"; for(n = 0; n < imp2.length; n++) { fe[n].value = imp2[n]; if(n == 1) updateImage; }			cform.className = "hide"; } else { others = o2; impSlow = true; fe[6].value = "Error, missing:"; for(i = 0; labels[i]; i++) if(!imp2[i]) fe[6].value += " " + labels[i]; }	} else fe[6].value = "Cancelling"; fe[6].setAttribute("readonly", 1); imp = ""; setTimeout(function {		fe[6].value = ;		fe[6].removeAttribute("readonly");		cform.className = ;	}, impSlow ? 3e3 : 500); }

function loadCheck { if(imgcrop.complete) { pc.onclick = findClick; pc.className = ""; if(window.gl) for(i = 0; gl[i]; i++) pc.appendChild(gl[i]); if(lastWidth === "") for(i = 2; i < 6; i++) fe[i].onkeyup = plusminus1pct; if(!mainKB) { (mainKB = new XMLHttpRequest).open('HEAD', '/wiki', false); mainKB.send; mainKB = mainKB.getResponseHeader("content-length"); loadtime = new Date; }		lastWidth = pc.firstChild.offsetWidth - scrBar; lastHeight = pc.firstChild.offsetHeight - scrBar; if(!fe[6].value && lastFile != fe[0].value) unCrop; lastFile = fe[0].value = imgs[0].alt.replace("File:", ""); setTimeout(updateCrop, 9); } else setTimeout(loadCheck, 99); }

function findClick(e) { if((e = e || window.event).shiftKey) undoClick; else { mouse = { x: e.clientX || e.pageX, y: e.clientY || e.pageY };		pc.x = pc.y = 0; for(xy = pc; xy; xy = xy.offsetParent) { pc.x += xy.offsetLeft; pc.y += xy.offsetTop; }		lastClick.unshift([(mouse.x - pc.x + (window.pageXOffset || document.documentElement.scrollLeft) + pc.scrollLeft) / lastWidth, (mouse.y - pc.y + (window.pageYOffset || document.documentElement.scrollTop) + pc.scrollTop) / lastHeight]); }	drawClick; }

function undoClick { lastClick.shift; if(lastClick[0]) drawClick; else clearClick; }

function scaleClick(index, op) { tO = [typeof "", typeof 1, typeof 0[0], typeof !0].indexOf(typeof op); return Math.round(Math[!tO ? op : "min"](lastClick[tO == 1 ? op : 0][index], lastClick[tO == 1 ? op : (tO == 3 ? 0 : 1)][index]) * (index ? lastHeight : lastWidth)); }

function glAnim { if(mc) { for(ga = 0; ga < 4; ga++) gl[ga].style.borderStyle = gl[ga].style.borderStyle == "dashed" ? "dotted" : "dashed"; setTimeout(glAnim, 99); } }

function drawClick { if(lastClick[0]) { if(!mc) { mc = []; gl = []; for(i = 0; i < 4; i++) { rows[i + 2].appendChild(mc[i] = document.createElement("td")); (gl[i] = document.createElement("div")).style.cssText = "border-width:" + (i < 2 ? "1px 0" : "0 1px") + ";border-color:rgba(0,0,0,0.7);border-" + (b2 = i < 2 ? "top" : "left") + "-color:#fff;border-" + b2 + "-color:rgba(255,255,255,0.7);"; pc.appendChild(gl[i]).className = "gl"; }			glAnim; }		if(lastClick.length == 1) { oCoord = [ [scaleClick(0, 0), scaleClick(1, 0)] ];			for(i = 0; mc[i]; i++) mc[i].innerHTML = ""; } else { oCoord = [ [scaleClick(0), scaleClick(1)], [scaleClick(0, "max"), scaleClick(1, "max")] ];			for(i = 0; i < 2; i++) { mc[i].innerHTML = Math.abs(oCoord[1][i] - oCoord[0][i]); mc[i + 2].innerHTML = oCoord[0][1 - i]; }		}		clickInfo.innerHTML = "Click history: " + oCoord[0].join(", ") + (oCoord[1] ? "; " + scaleClick(0, 1) + ", " + scaleClick(1, 1) + (lastClick[2] ? " (+" + (lastClick.length - 2) + " more)" : "") : ""); for(i = 0; i < 2; i++) { if(oCoord[i]) { gl[i].style.left = pc.offsetLeft + "px"; gl[i + 2].style.top = pc.offsetTop + "px"; gl[i].style.top = (oCoord[i][1] + pc.offsetTop - pc.scrollTop) + "px"; gl[i + 2].style.left = (oCoord[i][0] + pc.offsetLeft - pc.scrollLeft) + "px"; }			gl[i].style.width = (oCoord[i] && oCoord[i][1] - fe[4].value < fe[3].value && oCoord[i][1] > fe[4].value ? fe[2].value : 0) + "px"; gl[i + 2].style.height = (oCoord[i] && oCoord[i][0] - fe[5].value < fe[2].value && oCoord[i][0] > fe[5].value ? fe[3].value : 0) + "px"; }	} }

function clearClick { if(mc && rows[2].cells[2]) { for(i = 0; i < 4; i++) { rows[i + 2].removeChild(mc[i]); pc.removeChild(gl[i]); }		gl = mc = 0; clickInfo.innerHTML = "Click history cleared."; }	lastClick = []; }

function cropClick { if(mc && mc[0].innerHTML) { for(i = 0; i < 4; i++) fe[i + 2].value = mc[i].innerHTML; updateCrop; } else alert("No area selected."); }

function unCrop { fe[2].value = fe[1].value = lastWidth; fe[3].value = lastHeight; fe[4].value = fe[5].value = lastTopPct = lastLeftPct = 0; lastWidthPct = lastHeightPct = 1; if(lastFile == fe[0].value) setTimeout(updateCrop, 9); }

function initAutoCrop { document.body.appendChild(outer = document.createElement("div")).style.width = "100px"; widthNoScroll = outer.offsetWidth; outer.style.overflow = "scroll"; (inner = document.createElement("div")).style.width = "100%"; outer.appendChild(inner); scrBar = widthNoScroll - inner.offsetWidth; outer.parentNode.removeChild(outer); lastFile = lastWidth = lastHeight = ""; labels = ["Image", "bSize", "cWidth", "cHeight", "oTop", "oLeft"]; others = [], lastClick = [], imgs = []; autocrop.innerHTML = "    Crop to clicked area Uncrop image Suppress output newlines?  "; (cssNode = (document.head || document.getElementsByTagName("head")[0]).appendChild(document.createElement("style"))).type = "text/css"; (cssNode.styleSheet || cssNode)[cssNode.styleSheet ? "cssText" : "innerHTML"] = "#pc{overflow:scroll;}#cform input{width:16em;}#pc.hide,.hide input{visibility:hidden;}#cform textarea{width:100%;height:3em;}#cform table{border-spacing:0;}tr.break>td{border-top:2px solid #000;}[readonly],.cButton{background-color:#eee;}.cButton{cursor:pointer;outline:1px solid;text-align:center;vertical-align:middle;margin: 0 0.3em;padding: 0 0.5em;}#pc >:first-child{padding-bottom:" + scrBar + "px;padding-right:" + scrBar + "px;}.cButton,#pc>:first-child,.gl{display:inline-block;}.gl{position:absolute;z-index:9;border-style:dotted;height:0;width:0;}"; fe = cform.elements; rows = cform.firstChild.rows; mainKB = mc = 0; rows[1].cells[2].innerHTML = cb1.outerHTML.replace(1, 2) + rows[1].cells[2].innerHTML; if(!window.editform) window.onbeforeunload = function { if(lastWidth != fe[2].value || lastHeight != fe[3].value || window.gl) return "Unsaved work may be lost if you leave this page."; };	imgcrop.onload = loadCheck; imgcrop.onerror = function { imgs.shift; alert("Download failed. Try again later."); cform.className = ""; updateImage; };	autotemp.onclick = function { autotemp.setSelectionRange(0, autotemp.value.length); }; }