PluginProbe
Squeeze – Image Optimization & Compression, WEBP Conversion / 1.0
Squeeze – Image Optimization & Compression, WEBP Conversion v1.0
1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 trunk 1.0 1.1 1.2 1.3 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5 1.5.1 1.5.2 1.6 All 42 releases
squeeze / assets / js / script.js

script.js in Squeeze – Image Optimization & Compression, WEBP Conversion 1.0, at assets/js/script.js

336 lines 10.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 //import * as avif from '@jsquash/avif'; // TBD
2 //import * as webp from '@jsquash/webp'; // TBD
3 import * as jpeg from '@jsquash/jpeg';
4 import * as png from '@jsquash/png';
5 import optimise from '@jsquash/oxipng/optimise';
6 const { __ } = wp.i18n; // Import __() from wp.i18n
7
8 (function () {
9
10 const bulkBtn = document.querySelector("input[name='squeeze_bulk']")
11 const bulkLogInput = document.querySelector("[name='squeeze_bulk_log']")
12 const squeeze_bulk_ids = document.querySelector("input[name='squeeze_bulk_ids']")?.value ?? null;
13 const uncompressedIDs = squeeze_bulk_ids ? squeeze_bulk_ids.split(",") : [];
14
15 async function decode(sourceType, fileBuffer) {
16 switch (sourceType) {
17 //case 'avif':
18 // return await avif.decode(fileBuffer);
19 case 'jpeg':
20 return await jpeg.decode(fileBuffer);
21 case 'png':
22 return await png.decode(fileBuffer);
23 //case 'webp':
24 // return await webp.decode(fileBuffer);
25 default:
26 throw new Error(`Unknown source type: ${sourceType}`);
27 }
28 }
29
30 async function encode(outputType, imageData) {
31 const options = JSON.parse(squeeze.options);
32
33 switch (outputType) {
34 //case 'avif':
35 // return await avif.encode(imageData);
36 case 'jpeg':
37 const jpegOptions = {}
38 for (const [key, value] of Object.entries(options)) {
39 if (key.includes('jpeg')) {
40 const keyName = key.replace('jpeg_', '')
41 jpegOptions[keyName] = value
42 }
43 }
44 return await jpeg.encode(imageData, jpegOptions);
45 case 'png':
46 const pngOptions = {}
47 for (const [key, value] of Object.entries(options)) {
48 if (key.includes('png')) {
49 const keyName = key.replace('png_', '')
50 pngOptions[keyName] = value
51 }
52 }
53 return await png.encode(imageData, pngOptions);
54 //case 'webp':
55 // return await webp.encode(imageData);
56 default:
57 throw new Error(`Unknown output type: ${outputType}`);
58 }
59 }
60
61 async function convert(sourceType, outputType, fileBuffer) {
62 const imageData = await decode(sourceType, fileBuffer);
63 return encode(outputType, imageData);
64 }
65
66 function blobToBase64(blob) {
67 return new Promise((resolve, _) => {
68 const reader = new FileReader();
69 reader.onloadend = () => resolve(reader.result);
70 reader.readAsDataURL(blob);
71 });
72 }
73
74 async function showOutput(imageBuffer, outputType) {
75 const imageBlob = new Blob([imageBuffer], { type: `image/${outputType}` });
76 const base64String = await blobToBase64(imageBlob);
77
78 return base64String;
79 }
80
81 async function handleUpload(attachment, isBulk = false, isSingle = false, target = null) {
82 const attachmentData = attachment.attributes;
83 const url = attachmentData?.originalImageURL ?? attachmentData.url;
84 const mime = attachmentData.mime;
85 const name = attachmentData.name;
86 const filename = attachmentData?.originalImageName ?? attachmentData.filename;
87 const attachmentID = attachmentData.id;
88 const format = mime.split("/")[1];
89 const sourceType = format;
90 const outputType = format;
91 const options = JSON.parse(squeeze.options);
92
93 let imageBuffer;
94 let fileBuffer;
95 let base64;
96
97 if (format === "png") {
98 const pngOptions = {}
99 for (const [key, value] of Object.entries(options)) {
100 if (key.includes('png')) {
101 const keyName = key.replace('png_', '')
102 pngOptions[keyName] = value
103 }
104 }
105 imageBuffer = await fetch(url).then(res => res.arrayBuffer()).then(pngImageBuffer => optimise(pngImageBuffer, pngOptions));
106 } else {
107 let response = await fetch(url);
108 let blob = await response.blob();
109 let metadata = {
110 type: mime
111 };
112 let imageObj = new File([blob], name, metadata);
113 fileBuffer = await imageObj.arrayBuffer();
114
115 /*
116 if (window.Worker) {
117 //const myWorker = new Worker(new URL(`${squeeze.pluginUrl}/assets/js/worker.js`), { type: "module" });
118 const myWorker = new Worker(/* webpackChunkName: "foo-worker" */ /*new URL(`./worker.js`, import.meta.url));
119 myWorker.postMessage(
120 {
121 fileBuffer: fileBuffer,
122 sourceType: sourceType,
123 outputType: outputType,
124 }
125 );
126 console.log('Message posted to worker');
127
128 myWorker.onmessage = function(e) {
129 console.log('Message received from worker', e.data);
130 myWorker.terminate();
131 }
132 } else {
133 console.log('Your browser doesn\'t support web workers.');
134 }
135 */
136
137 imageBuffer = await convert(sourceType, outputType, fileBuffer);
138 base64 = await showOutput(imageBuffer, outputType);
139 }
140
141 let data = {
142 action: 'squeeze_update_attachment',
143 _ajax_nonce: squeeze.nonce,
144 filename: filename,
145 type: 'image',
146 format: format,
147 base64: base64,
148 attachmentID: attachmentID,
149 url: url,
150 }
151
152 jQuery.ajax({
153 url: squeeze.ajaxUrl,
154 type: 'POST',
155 data: data,
156 beforeSend: function () {
157 console.log('data', data)
158 if (isBulk)
159 bulkLogInput.value += `#${attachmentID}: ` + __('Compressed successfully, updating...', 'squeeze') + `\r\n`;
160 },
161 error: function (error) {
162 console.error(error)
163 if (target) {
164 target.closest("td").querySelector(".squeeze_status").innerText = __('An error has occured. Check the console for details.', 'squeeze')
165 target.remove();
166 }
167 },
168 success: function (response) {
169 console.log(response)
170 if (isBulk) {
171 if (response.success) {
172 bulkLogInput.value += `#${attachmentID}: ` + __('Updated successfully', 'squeeze') + `\r\n===============================\r\n`;
173 handleBulkUpload()
174 } else {
175 bulkLogInput.value += `#${attachmentID}: ${response.data}\r\n===============================\r\n`;
176 }
177 }
178 if (isSingle && target) {
179 target.closest("td").querySelector(".squeeze_status").innerText = response.data;
180 target.remove();
181 }
182 if (!isSingle && !isBulk) {
183 attachment.set('uploading', false) // resume uploading process
184 }
185 }
186 });
187
188 }
189
190 const handleBulkUpload = () => {
191 const data = {
192 action: 'squeeze_get_attachment',
193 _ajax_nonce: squeeze.nonce,
194 attachmentID: uncompressedIDs[0],
195 }
196
197 if (uncompressedIDs.length === 0) {
198 alert(__('All images have been compressed!', 'squeeze'))
199 bulkBtn.remove();
200 location.reload();
201 return;
202 }
203
204 bulkLogInput.value += `attachment #${uncompressedIDs[0]}: start compressing...\r\n`;
205
206 jQuery.ajax({
207 url: squeeze.ajaxUrl,
208 type: 'POST',
209 data: data,
210 error: function (error) {
211 console.error(error)
212 },
213 success: function (response) {
214 //console.log(response)
215 if (response.success) {
216 const responseData = response.data;
217 const attachment = {
218 attributes: {
219 url: responseData.url,
220 mime: responseData.mime,
221 name: responseData.name,
222 filename: responseData.filename,
223 id: responseData.id,
224 }
225 }
226 //console.log(attachment, 'attachment')
227 uncompressedIDs.shift();
228 handleUpload(attachment, true)
229 } else {
230 console.error(response.data)
231 }
232 }
233 });
234 }
235
236 function handleRestore(attachmentID, target) {
237 let data = {
238 action: 'squeeze_restore_attachment',
239 _ajax_nonce: squeeze.nonce,
240 attachmentID: attachmentID,
241 }
242
243 jQuery.ajax({
244 url: squeeze.ajaxUrl,
245 type: 'POST',
246 data: data,
247 beforeSend: function () {
248 target.disabled = true;
249 target.innerText = __('Restore in process...', 'squeeze')
250 },
251 error: function (error) {
252 console.error(error)
253 target.closest("td").querySelector(".squeeze_status").innerText = __('An error has occured. Check the console for details.', 'squeeze')
254 target.remove();
255 },
256 success: function (response) {
257 //console.log(response)
258 target.closest("td").querySelector(".squeeze_status").innerText = response.data; //__('Restored successfully', 'squeeze')
259 target.remove();
260 }
261 });
262 }
263
264 // Handle single compress button click
265 const handleSingleBtnClick = (event) => {
266 const attachmentID = event.target.dataset.attachment;
267
268 wp?.media?.attachment(attachmentID).fetch().then(function (data) {
269 const attachment = {
270 attributes: data
271 }
272 handleUpload(attachment, false, true, event.target)
273 });
274 }
275
276 // Handle restore button click
277 const handleRestoreBtnClick = (event) => {
278 const attachmentID = event.target.dataset.attachment;
279 handleRestore(attachmentID, event.target)
280 }
281
282 /**
283 * Handle single buttons click
284 */
285 function handleSingleButtonsClick() {
286 document.addEventListener("click", (e) => {
287 //console.log(e.target, 'e.target')
288 const singleBtnName = 'squeeze_compress_single';
289 const restoreBtnName = 'squeeze_restore';
290 if (e.target.getAttribute("name") === singleBtnName) {
291 e.target.disabled = true;
292 e.target.innerText = __('Compressing...', 'squeeze')
293 handleSingleBtnClick(e)
294 }
295 if (e.target.getAttribute("name") === restoreBtnName) {
296 e.target.disabled = true;
297 handleRestoreBtnClick(e)
298 }
299 })
300 }
301
302 handleSingleButtonsClick()
303
304
305 /**
306 * Handle bulk button click
307 */
308 bulkBtn?.addEventListener("click", (event) => {
309 if (uncompressedIDs.length === 0) {
310 return;
311 }
312
313 bulkBtn.disabled = true;
314 handleBulkUpload()
315
316 })
317
318 // https://wordpress.stackexchange.com/a/131295/186146 - override wp.Uploader.prototype.success
319 jQuery.extend(wp?.Uploader?.prototype, {
320 success: function (attachment) {
321 //console.log(attachment, 'success');
322 const options = JSON.parse(squeeze.options);
323 const isAutoCompress = options.auto_compress;
324 let isImage = attachment.attributes.type === 'image' &&
325 (attachment.attributes.subtype === 'jpeg' || attachment.attributes.subtype === 'png')
326
327 if (isImage && isAutoCompress) {
328 // set 'uploading' param to true, to pause the uploading process
329 attachment.set('uploading', true)
330 handleUpload(attachment)
331 }
332 },
333 });
334 })();
335
336 //console.log(JSON.parse(squeeze.options), 'squeeze.options')