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

function automake() {

if(!imgs[0]) return;

at = "{{CSS image crop";

for(i = 0; i < (6 + others.length); i++) at += (cNoBreaks.checked ? "|" : "\r\n| ") + (i < 6 ? labels[i] : others[i - 6][0]) + " = " + (i < 6 ? fe[i].value : others[i - 6][1]);

autotemp["inner" + (cssNode.styleSheet ? "Text" : "HTML")] = at + (cNoBreaks.checked ? "" : "\r\n") + "}}";

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 = "

ImageClick image to draw guide lines.
bSize
Clear history
cWidth
cHeight
oTop
oLeft
Import

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);

};

}