// ==UserScript== // @name 4chan Image Resizer // @namespace https://greasyfork.org/en/users/393416 // @version 2.5 // @description Automatically downscale images based on custom presets. Features image cropping and WebP conversion. Requires 4chan X. // @author greenronia // @match *://boards.4chan.org/* // @match *://boards.4channel.org/* // @require https://cdnjs.cloudflare.com/ajax/libs/spark-md5/3.0.0/spark-md5.js // @require https://unpkg.com/@daiyam/cropperjs@1.5.9-d2/dist/@daiyam/cropper.js // @resource cropper_css https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.9/cropper.css // @grant GM_getResourceText // @grant GM_addStyle // @icon https://i.imgur.com/hQp5BTf.png // @downloadURL none // ==/UserScript== // //Using SparkMD5 to generate image hashes - https://github.com/satazor/js-spark-md5 //Using @daiyam/Cropper.js fork to crop images - https://github.com/daiyam/cropperjs/tree/daiyam // //----------DEBUG MODE-------------// var DEBUG = false;//console // //--------CURRENT VERSION--------// const version = "2.5"; //-----------------------------// if(DEBUG) console.log("[ImageResizer] Initialized"); //CSS var cssTxt = GM_getResourceText ("cropper_css"); GM_addStyle (cssTxt); var style = document.createElement("style"); style.innerHTML = '' + '.centerImg { margin: 0; position: absolute; top: 50%; left: 50%; -ms-transform: translate(-50%, -50%); transform: translate(-50%, -50%); max-width: 100%; max-height: 100vh; height: auto; cursor: pointer; }\n' + '.settingsOverlay { background: rgba(0,0,0,0.8); display: none; height: 100%; left: 0; position: fixed; top: 0; width: 100%; z-index: 777; } \n' + '#pvOverlay { background: rgba(0,0,0,0.9); height: 100%; left: 0; position: fixed; top: 0; width: 100%; z-index: 777; text-align: center;} \n' + '#pvHeader { position: fixed; height: 35px; width: 100%; opacity: 0; -webkit-transition: opacity 0.5s ease-in-out;}\n' + '#pvHeader:hover { opacity: 0.8; -webkit-transition: none; }\n' + '.pvOpct { opacity: 0.7 !important; } \n' + '#imgResizeMenu { margin: 10% auto auto auto; width: 100%; width: 620px; padding: 2em; overflow: hidden; z-index: 8;}\n' + '#imgResizeMenu h3 { text-align: center; }\n' + '#imgResizeMenu a { cursor: pointer; }\n' + '#imgResizeMenu label { text-decoration-line: underline; }\n' + '#heplDiv summary { cursor: pointer; }\n' + '.settingsOverlay input[type=number], #manInput input[type=number] { -moz-appearance: textfield; text-align: right; }\n' + '.resizer-settings { padding-bottom: 10px }\n' + '#errMsg { color: red; text-align: center; }\n' + '#ruleTable { border-collapse: collapse; }\n' + '#ruleTable td, th { padding: 8px; text-align: left; border-bottom: 1pt solid; }\n' + '#QCTable { border-collapse: collapse; }\n' + '#QCTable td, th { padding: 8px; text-align: center; border-bottom: 1pt solid; }\n' + '#QCTable p { margin: auto; max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n' + '#inputContainer { text-align: center; padding-top: 1em; }\n' + '#inputContainer button { margin-top: 20px; }\n' + '.menuBtns { margin-left: 1em; }\n' + '#sideMenu { position: absolute; display: none; padding: 5px 0px 5px 0px; width: 105px; margin-left: -110px; margin-top: -2px;}\n' + '#manInput { position: absolute; padding: 10px 0px 10px 0px; width: 170px; margin-left: -175px; margin-top: -2px; text-align: center;}\n' + '.sideMenuElement { background: inherit; display: block; cursor: pointer; padding: 2px 10px 2px 10px; text-align: left;}\n' + '.downscale-menu-off { display: none; }\n' + '.downscale-menu-on { display: block !important; }'; var styleRef = document.querySelector("script"); styleRef.parentNode.insertBefore(style, styleRef); //Load settings getSettings(); getPresets(); getQCList(); //local version check against current version (function () { if (version.localeCompare(getSettings().version, undefined, { numeric: true, sensitivity: 'base' }) >= 1) { var settings = getSettings(); settings.version = version; settings.convertOutput = "image/png"; localStorage.setItem("downscale-settings", JSON.stringify(settings)); var info = '4chan Image Resizer updated to version ' + version; var msgDetail = {type: 'info', content: info, lifetime: 10}; var msgEvent = new CustomEvent('CreateNotification', {bubbles: true, detail: msgDetail}); document.dispatchEvent(msgEvent); } })(); function getSettings() { if (JSON.parse(localStorage.getItem("downscale-settings"))) { var settings = JSON.parse(localStorage.getItem("downscale-settings")); } else { settings = { enabled:true, notify:true, convert:true, convertOutput:"image/png", jpegQuality:0.92, shortcut:true , cropOutput:"image/png", version:"2.4"}; localStorage.setItem("downscale-settings", JSON.stringify(settings)); } return settings; } function getPresets() { if (JSON.parse(localStorage.getItem("downscale-presets"))) { var presets = JSON.parse(localStorage.getItem("downscale-presets")); } else { presets = []; } return presets; } function getQCList() { if (JSON.parse(localStorage.getItem("downscale-qclist"))) { var QCList = JSON.parse(localStorage.getItem("downscale-qclist")); } else { QCList = []; } return QCList; } //*************************************************************************************// // MAIN PROCESS //*************************************************************************************// //Checking if QuickReply dialog is open. | Do stuff only when QR box is open. document.addEventListener('QRDialogCreation', function(listenForQRDC) { var checkBox = document.getElementById("imgResize"); var sideMenu = document.getElementById("sideMenuArrow"); //Checking if the "resize" check box and "side menu" already exist if (!sideMenu) { appendSideMenu(); } if (!checkBox) { appendCheckBox(); } //Listening for clicks on check box document.getElementById("imgResize").addEventListener("click", checkState); checkState(1); if(DEBUG) console.log("[QRFile] Listening..."); //QRFile | Listening for QRFile, in response to: QRGetFile | Request File document.addEventListener('QRFile', function(GetFile) { if(DEBUG) console.log("[QRFile] File served: " + GetFile.detail); //Remove "Remember" option upon adding a (new) file. removeRemOption(); const file = GetFile.detail; //Initialize an instance of a FileReader const reader = new FileReader(); //Checking whether the file is JPG or PNG or WebPiss if (file.type == "image/jpeg" || file.type == "image/png" || file.type == "image/webp") { if(DEBUG) console.log("Acceptable File type: " + file.type); //add
function clearErr() { document.getElementById("errMsg").innerHTML = ""; }
//Checks for any logic errors (upscaling)
function basicCheck(edit, rulePos) {
var inWidth = parseInt(document.getElementById("inWidth").value);
var inHeight = parseInt(document.getElementById("inHeight").value);
var outWidth = parseInt(document.getElementById("outWidth").value);
var outHeight = parseInt(document.getElementById("outHeight").value);
var imgType = parseInt(document.getElementById("imgType").value);
if (outWidth <= 0 || outHeight <= 0) { document.getElementById("errMsg").innerHTML = "Invalid output dimensions"; return}
else if (inWidth < outWidth || inHeight < outHeight) { document.getElementById("errMsg").innerHTML = "Cannot upscale images"; return}
else finalCheck(edit, imgType, inWidth, inHeight, outWidth, outHeight, rulePos);
return;
}
//Checks for any rule overlaps
// ([0] - Image type, [1] - Input width, [2] - Input height, [3] - Output width, [4] - Output height)
function finalCheck(edit, imgType, inWidth, inHeight, outWidth, outHeight, rulePos) {
var e = document.getElementById("imgType");
var format = e.options[e.selectedIndex].text;
var presetString = imgType + ":" + inWidth + ":" + inHeight + ":" + outWidth + ":" + outHeight;
var presets = getPresets();
if (presets.length > 0) {
var rule = [];
var presetCount = presets.length;
for (var i = 0; i < presetCount; i++) {
if (edit && i === rulePos) continue;
rule[i] = presets[i].split(":");
if (presetString == presets[i]) { document.getElementById("errMsg").innerHTML = "Exact preset already exists"; return }
else if ((inWidth == rule[i][1] && inHeight == rule[i][2]) && (imgType == rule[i][0] || rule[i][0] == 0)) { document.getElementById("errMsg").innerHTML = "Preset with the same input dimensions for " + format + " format already exists"; return }
}
}
//save preset
clearErr();
if (edit) presets[rulePos] = presetString;
else presets.push(presetString);
localStorage.setItem("downscale-presets", JSON.stringify(presets));
//rebuild list
document.getElementById("ruleTable").tBodies.item(0).innerHTML = "";
printList();
//hide / display
document.getElementById("ruleInput").remove();
document.getElementById("addRule").style.display = "inline";
return;
}
//Check if possible to calculate output WIDTH
function aspectCheckH() {
var inWidth = document.getElementById("inWidth").value;
var inHeight = document.getElementById("inHeight").value;
var outWidth = document.getElementById("outWidth").value;
var outHeight = document.getElementById("outHeight").value;
if (outHeight > 0) {
if (parseInt(inHeight) >= parseInt(outHeight)) {
calcAspect("width", inWidth, inHeight, outHeight);
clearErr();
}
else {
document.getElementById("errMsg").innerHTML = "Cannot upscale images";
}
}
}
//Check if possible to calculate output HEIGHT
function aspectCheckW() {
var inWidth = document.getElementById("inWidth").value;
var inHeight = document.getElementById("inHeight").value;
var outWidth = document.getElementById("outWidth").value;
var outHeight = document.getElementById("outHeight").value;
if (outWidth > 0) {
if (parseInt(inWidth) >= parseInt(outWidth)) {
calcAspect("height", inWidth, inHeight, outWidth);
clearErr();
}
else {
document.getElementById("errMsg").innerHTML = "Cannot upscale images";
}
}
}
//Aspect ratio calculation (finds the other output dimension based on given exact input dimensions)
function calcAspect(dimension, w, h, output) {
if (dimension == "width") {
var width = output / h * w;
document.getElementById("outWidth").value = Math.round(width);
}
if (dimension == "height") {
var height = output / w * h;
document.getElementById("outHeight").value = Math.round(height);
}
}
//Aspect ratio calculation for Manual Resize (finds the other output dimension based on given exact input dimensions)
function calcResAspect(dimension, w, h, output) {
if (dimension == "width") {
var width = h / w * output;
document.getElementById("resHeight").value = Math.round(width);
}
if (dimension == "height") {
var height = w / h * output;
document.getElementById("resWidth").value = Math.round(height);
}
}
//Populate Presets list
function printList() {
var presets = getPresets();
var list = document.getElementById("imgResizeList");
var table = document.getElementById("ruleTable");
if (presets.length > 0) {
var rule = [];
var presetCount = presets.length;
for (let i = 0; i < presetCount; i++) {
rule[i] = presets[i].split(":");
switch (parseInt(rule[i][0])) {
case 0:
rule[i][0] = "PNG/JPEG";
break;
case 1:
rule[i][0] = "PNG";
break;
case 2:
rule[i][0] = "JPEG";
}
let delRow = document.createElement("a");
let editRow = document.createElement("a");
delRow.innerHTML = "delete";
editRow.innerHTML = "edit";
//delete a rule and rebuild the list
delRow.onclick = function() {
if (document.getElementById("inputContainer")) document.getElementById("inputContainer").innerHTML = "";
presets.splice(delRow.parentElement.parentElement.sectionRowIndex, 1);
localStorage.setItem("downscale-presets", JSON.stringify(presets));
table.tBodies.item(0).innerHTML = "";
printList();
clearErr();
document.getElementById("addRule").style.display = "inline";
};
editRow.onclick = function() { inputUI(true, rule[i], i); clearErr(); };
//Array contents: [0] - Image type, [1] - Input width, [2] - Input height, [3] - Output width, [4] - Output height
var row = table.tBodies.item(0).insertRow(-1);
row.insertCell(0).innerHTML = rule[i][0];
row.insertCell(1).innerHTML = '[ ' + rule[i][1] + ' x ' + rule[i][2] + ' ]';
row.insertCell(2).innerHTML = '→';
row.insertCell(3).innerHTML = '[ ' + rule[i][3] + ' x ' + rule[i][4] + ' ]';
row.insertCell(4).appendChild(editRow);
row.insertCell(5).appendChild(delRow);
}
}
}
//Input field
function inputUI(edit, rule, rulePos) {
if (document.getElementById("inputContainer")) document.getElementById("inputContainer").innerHTML = "";
document.getElementById("addRule").style.display = "none";
var inputDiv = document.getElementById("inputContainer");
var input = document.createElement("div");
var discardRuleBtn = document.createElement("button");
discardRuleBtn.innerHTML = "Cancel";
discardRuleBtn.style.margin = "auto 0 0 10px";
var saveRuleBtn = document.createElement("button");
saveRuleBtn.innerHTML = "Save";
input.id = "ruleInput";
//Rules form
input.innerHTML = '' +
'' +
' ' +
'' +
' x ' +
'' +
' ' +
' → x ' +
'
';
inputDiv.appendChild(input);
var inWidth = document.getElementById("inWidth");
var inHeight = document.getElementById("inHeight");
var outWidth = document.getElementById("outWidth");
var outHeight = document.getElementById("outHeight");
if (edit) {
switch (rule[0]) {
case "PNG/JPEG":
document.getElementById("imgType").selectedIndex = 0;
break;
case "PNG":
document.getElementById("imgType").selectedIndex = 1;
break;
case "JPEG":
document.getElementById("imgType").selectedIndex = 2;
}
inWidth.value = rule[1];
inHeight.value = rule[2];
outWidth.value = rule[3];
outHeight.value = rule[4];
}
//Listen for user input on target dimension input fields to automatically calculate aspect ratio
outWidth.addEventListener("input", aspectCheckW);
outHeight.addEventListener("input", aspectCheckH);
inWidth.onkeypress = function() { outHeight.value = 0; outWidth.value = 0; return isNumber(event); };
inHeight.onkeypress = function() { outHeight.value = 0; outWidth.value = 0; return isNumber(event); };
outWidth.onkeypress = function() { return isNumber(event); };
outHeight.onkeypress = function() { return isNumber(event); };
input.appendChild(saveRuleBtn);
input.appendChild(discardRuleBtn);
discardRuleBtn.onclick = function(){ document.getElementById(input.id).remove(); document.getElementById("addRule").style.display = "inline"; clearErr();};
saveRuleBtn.onclick = function() { if (edit) basicCheck(true, rulePos); else basicCheck(false); };
}
//Populate Quick Convert List table
function printQCList() {
var QCList = getQCList();
var list = document.getElementById("QCList");
var table = document.getElementById("QCTable");
var filterCount = QCList.length;
if (filterCount > 0) {
var QCFilter = [];
for (let i = 0; i < filterCount; i++) {
QCFilter[i] = QCList[i].split(":");
let delRow = document.createElement("a");
delRow.innerHTML = "delete";
delRow.onclick = function() {
QCList.splice(delRow.parentElement.parentElement.sectionRowIndex, 1);
localStorage.setItem("downscale-qclist", JSON.stringify(QCList));
table.tBodies.item(0).innerHTML = "";
printQCList();
};
//QCList Array: [0] - Filetype, [1] - Image Width, [2] - Image Height, [3] - Original Filesize, [4] - New Filesize, [5] - Filename, [6] - Image Base64 MD5 Hash
var row = table.tBodies.item(0).insertRow(-1);
row.insertCell(0).innerHTML = QCFilter[i][0];
row.insertCell(1).innerHTML = '[ ' + QCFilter[i][1] + ' x ' + QCFilter[i][2] + ' ]';
row.insertCell(2).innerHTML = QCFilter[i][3];
row.insertCell(3).innerHTML = '→';
row.insertCell(4).innerHTML = QCFilter[i][4];
row.insertCell(5).innerHTML = '
' + QCFilter[i][5] + '
'; row.insertCell(6).appendChild(delRow); } } } //*************************************************************************************// // MENUS // //*************************************************************************************// function appendSettings() { //Button-------------------------------------------------------- var span = document.createElement("span"); var button = document.createElement("a"); button.id = "imgResizeSettings"; button.className += "fa fa-cog"; button.style = "cursor: pointer;"; button.title = "Image Resizer Settings"; var ref = document.getElementById('shortcut-settings'); ref.insertBefore(span, parent.nextSibling); span.appendChild(button); //Overlay | imgResizeOverlay------------------------------------ var overlay = document.createElement("div"); overlay.id = "imgResizeOverlay"; overlay.classList.add("settingsOverlay"); document.body.appendChild(overlay); //Settings menu links | imgResizeMenu--------------------------- var menu = document.createElement("div"); menu.id = "imgResizeMenu"; menu.classList.add("dialog"); overlay.appendChild(menu); var close = document.createElement("a"); close.className += "close fa fa-times"; close.style = "float: right;"; close.title = "Close"; menu.insertAdjacentElement('afterbegin', close); //Settings var settingsBtn = document.createElement("a"); settingsBtn.innerHTML += "Settings"; settingsBtn.classList.add("menuBtns"); settingsBtn.style = "font-weight: bold;"; settingsBtn.onclick = function() { settingsDiv.className = "downscale-menu-on"; presetsDiv.className = "downscale-menu-off"; QCListDiv.className = "downscale-menu-off"; helpDiv.className = "downscale-menu-off"; settingsBtn.style = "font-weight: bold;"; presetsBtn.style = ""; QCListBtn.style = ""; helpBtn.style = ""; }; menu.appendChild(settingsBtn); //Presets var presetsBtn = document.createElement("a"); presetsBtn.innerHTML += "Presets"; presetsBtn.classList.add("menuBtns"); presetsBtn.onclick = function() { settingsDiv.className = "downscale-menu-off"; presetsDiv.className = "downscale-menu-on"; QCListDiv.className = "downscale-menu-off"; helpDiv.className = "downscale-menu-off"; settingsBtn.style = ""; presetsBtn.style = "font-weight: bold;"; QCListBtn.style = ""; helpBtn.style = ""; }; menu.appendChild(presetsBtn); //Quick Convert List var QCListBtn = document.createElement("a"); QCListBtn.innerHTML += "Quick Convert"; QCListBtn.classList.add("menuBtns"); QCListBtn.onclick = function() { settingsDiv.className = "downscale-menu-off"; presetsDiv.className = "downscale-menu-off"; QCListDiv.className = "downscale-menu-on"; helpDiv.className = "downscale-menu-off"; settingsBtn.style = ""; presetsBtn.style = ""; QCListBtn.style = "font-weight: bold;"; helpBtn.style = ""; }; menu.appendChild(QCListBtn); //Help var helpBtn = document.createElement("a"); helpBtn.innerHTML += "About"; helpBtn.classList.add("menuBtns"); helpBtn.onclick = function() { settingsDiv.className = "downscale-menu-off"; presetsDiv.className = "downscale-menu-off"; QCListDiv.className = "downscale-menu-off"; helpDiv.className = "downscale-menu-on"; settingsBtn.style = ""; presetsBtn.style = ""; QCListBtn.style = ""; helpBtn.style = "font-weight: bold;"; }; menu.appendChild(helpBtn); var hr = document.createElement("hr"); hr.style.borderColor = getHRColor(); menu.appendChild(hr); //Content divs| imgResizeContent--------------------------------- var content = document.createElement("div"); content.id = "imgResizeContent"; menu.appendChild(content); content.innerHTML = ""; var errMsg = document.createElement("p"); errMsg.id = "errMsg"; //Settings var settingsDiv = document.createElement("div"); settingsDiv.id = "settingsDiv"; settingsDiv.classList.add("downscale-menu-on"); content.appendChild(settingsDiv); //Presets var presetsDiv = document.createElement("div"); presetsDiv.id = "presetsDiv"; presetsDiv.classList.add("downscale-menu-off"); presetsDiv.style.textAlign = "center"; content.appendChild(presetsDiv); //Quick Convert List var QCListDiv = document.createElement("div"); QCListDiv.id = "QCListDiv"; QCListDiv.classList.add("downscale-menu-off"); content.appendChild(QCListDiv); //Help var helpDiv = document.createElement("div"); helpDiv.id = "heplDiv"; helpDiv.classList.add("downscale-menu-off"); content.appendChild(helpDiv); //-------------------------------------------------------------- var title = document.createElement("h3"); title.innerHTML = "Image Resizer Settings"; settingsDiv.appendChild(title); //Enable Resizer------------------------------------------------ var enableDiv = document.createElement("div"); enableDiv.classList.add("resizer-settings"); enableDiv.innerHTML = '' + '' + ': ' + 'Enable 4chan Image Resizer by default.'; settingsDiv.appendChild(enableDiv); var enableSet = document.getElementById("enableSet"); enableSet.checked = getSettings().enabled; enableSet.oninput = function() { //remove side menu options upon disabling ImageResizer if (!enableSet.checked) { removeCropOption(); removeQCOption(); removeRemOption(); removePreviewOption(); } var settings = getSettings(); settings.enabled = enableSet.checked; document.getElementById("imgResize").checked = enableSet.checked; localStorage.setItem("downscale-settings", JSON.stringify(settings)); }; //Enable Shortcut----------------------------------------------- var shortcutDiv = document.createElement("div"); shortcutDiv.classList.add("resizer-settings"); shortcutDiv.innerHTML = '' + '' + ': ' + 'Enable "Quick Convert" shortcut. Ctrl + Q by default.'; settingsDiv.appendChild(shortcutDiv); var shortcutSet = document.getElementById("shortcutSet"); shortcutSet.checked = getSettings().shortcut; shortcutSet.oninput = function() { var settings = getSettings(); settings.shortcut = shortcutSet.checked; localStorage.setItem("downscale-settings", JSON.stringify(settings)); }; //Display notifications----------------------------------------- var notifySetDiv = document.createElement("div"); notifySetDiv.classList.add("resizer-settings"); notifySetDiv.innerHTML = '' + '' + ': ' + 'Display a notification when an image is downscaled.'; settingsDiv.appendChild(notifySetDiv); var notifySet = document.getElementById('displaySet'); notifySet.checked = getSettings().notify; notifySet.oninput = function() { var settings = getSettings(); settings.notify = notifySet.checked; localStorage.setItem("downscale-settings", JSON.stringify(settings)); }; //Convert WebP------------------------------------- var convertSetDiv = document.createElement("div"); convertSetDiv.classList.add("resizer-settings"); convertSetDiv.innerHTML = '' + '' + '' + ': ' + 'Automatically convert WebP images to selected format.'; settingsDiv.appendChild(convertSetDiv); var convertSet = document.getElementById('convertSet'); convertSet.checked = getSettings().convert; var convertOutSet = document.getElementById('convertOut'); convertOutSet.value = getSettings().convertOutput; //very lazy copy... convertSet.oninput = function() { var settings = getSettings(); settings.convert = convertSet.checked; settings.convertOutput = convertOutSet.value; localStorage.setItem("downscale-settings", JSON.stringify(settings)); }; //...paste convertOutSet.oninput = function() { var settings = getSettings(); settings.convert = convertSet.checked; settings.convertOutput = convertOutSet.value; localStorage.setItem("downscale-settings", JSON.stringify(settings)); }; //Set JPEG quality---------------------------------------------- //RegExp ^$|^[1-9][0-9]?$|^100$ //Only numbers between 1 and 100, including an empty string (that is not written in storage) //JPEG quality value is still stored as a decimal number. var qualitySetDiv = document.createElement("div"); qualitySetDiv.classList.add("resizer-settings"); qualitySetDiv.innerHTML = '' + '' + ': ' + 'A number between 1 and 100 indicating the output image quality.'; settingsDiv.appendChild(qualitySetDiv); var inputField = document.getElementById('imgQuality'); inputField.value = getSettings().jpegQuality * 100; //Check input field validity and store correct value inputField.oninput = function() { var inputField = document.getElementById('imgQuality'); var r = new RegExp(/^$|^[1-9][0-9]?$|^100$/); if(r.test(inputField.value) && inputField.value != "") { inputField.setCustomValidity(""); var settings = getSettings(); settings.jpegQuality = inputField.value / 100; localStorage.setItem("downscale-settings", JSON.stringify(settings)); } else if (inputField.value == ""){ inputField.setCustomValidity("Input a number between 1 and 100.\nCurrent set value: " + getSettings().jpegQuality * 100); inputField.reportValidity(); } else { inputField.setCustomValidity("Input a number between 1 and 100.\nCurrent set value: " + getSettings().jpegQuality * 100); inputField.reportValidity(); inputField.value = getSettings().jpegQuality * 100; } }; //Cropper Settings----------------------------------------------- /* For future use var title2 = document.createElement("h3"); title2.innerHTML = "Image Cropper Settings"; settingsDiv.appendChild(title2); */ //Crop output format--------------------------------------------- var cropOutDiv = document.createElement("div"); cropOutDiv.classList.add("resizer-settings"); cropOutDiv.innerHTML = '' + ' ' + ': ' + 'Set the desired output format for cropped images.'; settingsDiv.appendChild(cropOutDiv); var cropOutSet = document.getElementById('cropOut'); cropOutSet.value = getSettings().cropOutput; cropOutSet.oninput = function() { var settings = getSettings(); settings.cropOutput = cropOutSet.value; localStorage.setItem("downscale-settings", JSON.stringify(settings)); }; //Preset table | ruleTable---------------------------------------- var tableWrapper = document.createElement("div"); tableWrapper.style.overflowY = "auto"; tableWrapper.style.maxHeight = "220px"; var table = document.createElement("table"); var thead = document.createElement("thead"); var tbody = document.createElement("tbody"); var presetsTitle = document.createElement("h3"); presetsTitle.innerHTML = "Presets"; presetsDiv.appendChild(presetsTitle); table.appendChild(thead); table.appendChild(tbody); table.id = "ruleTable"; var row = thead.insertRow(0); row.insertCell(0).outerHTML = "Images on this list will be automatically converted to JPEG with a quality setting of 92.
"; QCTable.appendChild(QCThead); QCTable.appendChild(QCTbody); QCTable.id = "QCTable"; var QCRow = QCThead.insertRow(0); QCRow.insertCell(0).outerHTML = "