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 = "
(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);
};
}