wp_back/wp-content/plugins/squeeze/assets/js/script.js
2024-05-20 15:37:46 +03:00

337 lines
11 KiB
JavaScript

//import * as avif from '@jsquash/avif'; // TBD
//import * as webp from '@jsquash/webp'; // TBD
import * as jpeg from '@jsquash/jpeg';
import * as png from '@jsquash/png';
import optimise from '@jsquash/oxipng/optimise';
const { __ } = wp.i18n; // Import __() from wp.i18n
(function () {
const bulkBtn = document.querySelector("input[name='squeeze_bulk']")
const bulkLogInput = document.querySelector("[name='squeeze_bulk_log']")
const squeeze_bulk_ids = document.querySelector("input[name='squeeze_bulk_ids']")?.value ?? null;
const uncompressedIDs = squeeze_bulk_ids ? squeeze_bulk_ids.split(",") : [];
async function decode(sourceType, fileBuffer) {
switch (sourceType) {
//case 'avif':
// return await avif.decode(fileBuffer);
case 'jpeg':
return await jpeg.decode(fileBuffer);
case 'png':
return await png.decode(fileBuffer);
//case 'webp':
// return await webp.decode(fileBuffer);
default:
throw new Error(`Unknown source type: ${sourceType}`);
}
}
async function encode(outputType, imageData) {
const options = JSON.parse(squeeze.options);
switch (outputType) {
//case 'avif':
// return await avif.encode(imageData);
case 'jpeg':
const jpegOptions = {}
for (const [key, value] of Object.entries(options)) {
if (key.includes('jpeg')) {
const keyName = key.replace('jpeg_', '')
jpegOptions[keyName] = value
}
}
return await jpeg.encode(imageData, jpegOptions);
case 'png':
const pngOptions = {}
for (const [key, value] of Object.entries(options)) {
if (key.includes('png')) {
const keyName = key.replace('png_', '')
pngOptions[keyName] = value
}
}
return await png.encode(imageData, pngOptions);
//case 'webp':
// return await webp.encode(imageData);
default:
throw new Error(`Unknown output type: ${outputType}`);
}
}
async function convert(sourceType, outputType, fileBuffer) {
const imageData = await decode(sourceType, fileBuffer);
return encode(outputType, imageData);
}
function blobToBase64(blob) {
return new Promise((resolve, _) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(blob);
});
}
async function showOutput(imageBuffer, outputType) {
const imageBlob = new Blob([imageBuffer], { type: `image/${outputType}` });
const base64String = await blobToBase64(imageBlob);
return base64String;
}
async function handleUpload(attachment, isBulk = false, isSingle = false, target = null) {
const attachmentData = attachment.attributes;
const url = attachmentData?.originalImageURL ?? attachmentData.url;
const mime = attachmentData.mime;
const name = attachmentData.name;
const filename = attachmentData?.originalImageName ?? attachmentData.filename;
const attachmentID = attachmentData.id;
const format = mime.split("/")[1];
const sourceType = format;
const outputType = format;
const options = JSON.parse(squeeze.options);
let imageBuffer;
let fileBuffer;
let base64;
if (format === "png") {
const pngOptions = {}
for (const [key, value] of Object.entries(options)) {
if (key.includes('png')) {
const keyName = key.replace('png_', '')
pngOptions[keyName] = value
}
}
imageBuffer = await fetch(url).then(res => res.arrayBuffer()).then(pngImageBuffer => optimise(pngImageBuffer, pngOptions));
base64 = await showOutput(imageBuffer, outputType);
} else {
let response = await fetch(url);
let blob = await response.blob();
let metadata = {
type: mime
};
let imageObj = new File([blob], name, metadata);
fileBuffer = await imageObj.arrayBuffer();
/*
if (window.Worker) {
//const myWorker = new Worker(new URL(`${squeeze.pluginUrl}/assets/js/worker.js`), { type: "module" });
const myWorker = new Worker(/* webpackChunkName: "foo-worker" */ /*new URL(`./worker.js`, import.meta.url));
myWorker.postMessage(
{
fileBuffer: fileBuffer,
sourceType: sourceType,
outputType: outputType,
}
);
console.log('Message posted to worker');
myWorker.onmessage = function(e) {
console.log('Message received from worker', e.data);
myWorker.terminate();
}
} else {
console.log('Your browser doesn\'t support web workers.');
}
*/
imageBuffer = await convert(sourceType, outputType, fileBuffer);
base64 = await showOutput(imageBuffer, outputType);
}
let data = {
action: 'squeeze_update_attachment',
_ajax_nonce: squeeze.nonce,
filename: filename,
type: 'image',
format: format,
base64: base64,
attachmentID: attachmentID,
url: url,
}
jQuery.ajax({
url: squeeze.ajaxUrl,
type: 'POST',
data: data,
beforeSend: function () {
console.log('data', data)
if (isBulk)
bulkLogInput.value += `#${attachmentID}: ` + __('Compressed successfully, updating...', 'squeeze') + `\r\n`;
},
error: function (error) {
console.error(error)
if (target) {
target.closest("td").querySelector(".squeeze_status").innerText = __('An error has occured. Check the console for details.', 'squeeze')
target.remove();
}
},
success: function (response) {
console.log(response)
if (isBulk) {
if (response.success) {
bulkLogInput.value += `#${attachmentID}: ` + __('Updated successfully', 'squeeze') + `\r\n===============================\r\n`;
handleBulkUpload()
} else {
bulkLogInput.value += `#${attachmentID}: ${response.data}\r\n===============================\r\n`;
}
}
if (isSingle && target) {
target.closest("td").querySelector(".squeeze_status").innerText = response.data;
target.remove();
}
if (!isSingle && !isBulk) {
attachment.set('uploading', false) // resume uploading process
}
}
});
}
const handleBulkUpload = () => {
const data = {
action: 'squeeze_get_attachment',
_ajax_nonce: squeeze.nonce,
attachmentID: uncompressedIDs[0],
}
if (uncompressedIDs.length === 0) {
alert(__('All images have been compressed!', 'squeeze'))
bulkBtn.remove();
location.reload();
return;
}
bulkLogInput.value += `attachment #${uncompressedIDs[0]}: start compressing...\r\n`;
jQuery.ajax({
url: squeeze.ajaxUrl,
type: 'POST',
data: data,
error: function (error) {
console.error(error)
},
success: function (response) {
//console.log(response)
if (response.success) {
const responseData = response.data;
const attachment = {
attributes: {
url: responseData.url,
mime: responseData.mime,
name: responseData.name,
filename: responseData.filename,
id: responseData.id,
}
}
//console.log(attachment, 'attachment')
uncompressedIDs.shift();
handleUpload(attachment, true)
} else {
console.error(response.data)
}
}
});
}
function handleRestore(attachmentID, target) {
let data = {
action: 'squeeze_restore_attachment',
_ajax_nonce: squeeze.nonce,
attachmentID: attachmentID,
}
jQuery.ajax({
url: squeeze.ajaxUrl,
type: 'POST',
data: data,
beforeSend: function () {
target.disabled = true;
target.innerText = __('Restore in process...', 'squeeze')
},
error: function (error) {
console.error(error)
target.closest("td").querySelector(".squeeze_status").innerText = __('An error has occured. Check the console for details.', 'squeeze')
target.remove();
},
success: function (response) {
//console.log(response)
target.closest("td").querySelector(".squeeze_status").innerText = response.data; //__('Restored successfully', 'squeeze')
target.remove();
}
});
}
// Handle single compress button click
const handleSingleBtnClick = (event) => {
const attachmentID = event.target.dataset.attachment;
wp?.media?.attachment(attachmentID).fetch().then(function (data) {
const attachment = {
attributes: data
}
handleUpload(attachment, false, true, event.target)
});
}
// Handle restore button click
const handleRestoreBtnClick = (event) => {
const attachmentID = event.target.dataset.attachment;
handleRestore(attachmentID, event.target)
}
/**
* Handle single buttons click
*/
function handleSingleButtonsClick() {
document.addEventListener("click", (e) => {
//console.log(e.target, 'e.target')
const singleBtnName = 'squeeze_compress_single';
const restoreBtnName = 'squeeze_restore';
if (e.target.getAttribute("name") === singleBtnName) {
e.target.disabled = true;
e.target.innerText = __('Compressing...', 'squeeze')
handleSingleBtnClick(e)
}
if (e.target.getAttribute("name") === restoreBtnName) {
e.target.disabled = true;
handleRestoreBtnClick(e)
}
})
}
handleSingleButtonsClick()
/**
* Handle bulk button click
*/
bulkBtn?.addEventListener("click", (event) => {
if (uncompressedIDs.length === 0) {
return;
}
bulkBtn.disabled = true;
handleBulkUpload()
})
// https://wordpress.stackexchange.com/a/131295/186146 - override wp.Uploader.prototype.success
jQuery.extend(wp?.Uploader?.prototype, {
success: function (attachment) {
//console.log(attachment, 'success');
const options = JSON.parse(squeeze.options);
const isAutoCompress = options.auto_compress;
let isImage = attachment.attributes.type === 'image' &&
(attachment.attributes.subtype === 'jpeg' || attachment.attributes.subtype === 'png')
if (isImage && isAutoCompress) {
// set 'uploading' param to true, to pause the uploading process
attachment.set('uploading', true)
handleUpload(attachment)
}
},
});
})();
//console.log(JSON.parse(squeeze.options), 'squeeze.options')