This commit is contained in:
2024-05-20 15:37:46 +03:00
commit 00b7dbd0b7
10404 changed files with 3285853 additions and 0 deletions

View File

@ -0,0 +1,22 @@
"use strict";
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
(self["webpackChunk"] = self["webpackChunk"] || []).push([["node_modules_jsquash_oxipng_codec_pkg-parallel_index_js"],{
/***/ "./node_modules/@jsquash/oxipng/codec/pkg-parallel/index.js":
/*!******************************************************************!*\
!*** ./node_modules/@jsquash/oxipng/codec/pkg-parallel/index.js ***!
\******************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* empty/unused harmony star reexport */\nObject(function webpackMissingModule() { var e = new Error(\"Cannot find module './optimise'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }());\n\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/oxipng/codec/pkg-parallel/index.js?");
/***/ })
}]);

View File

@ -0,0 +1,157 @@
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js":
/*!***************************************************************************************************************************!*\
!*** ./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js ***!
\***************************************************************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"startWorkers\": () => (/* binding */ startWorkers)\n/* harmony export */ });\n/**\n * Copyright 2021 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Note: we use `wasm_bindgen_worker_`-prefixed message types to make sure\n// we can handle bundling into other files, which might happen to have their\n// own `postMessage`/`onmessage` communication channels.\n//\n// If we didn't take that into the account, we could send much simpler signals\n// like just `0` or whatever, but the code would be less resilient.\n\nfunction waitForMsgType(target, type) {\n return new Promise(resolve => {\n target.addEventListener('message', function onMsg({ data }) {\n if (data == null || data.type !== type) return;\n target.removeEventListener('message', onMsg);\n resolve(data);\n });\n });\n}\n\nwaitForMsgType(self, 'wasm_bindgen_worker_init').then(async data => {\n // # Note 1\n // Our JS should have been generated in\n // `[out-dir]/snippets/wasm-bindgen-rayon-[hash]/workerHelpers.js`,\n // resolve the main module via `../../..`.\n //\n // This might need updating if the generated structure changes on wasm-bindgen\n // side ever in the future, but works well with bundlers today. The whole\n // point of this crate, after all, is to abstract away unstable features\n // and temporary bugs so that you don't need to deal with them in your code.\n //\n // # Note 2\n // This could be a regular import, but then some bundlers complain about\n // circular deps.\n //\n // Dynamic import could be cheap if this file was inlined into the parent,\n // which would require us just using `../../..` in `new Worker` below,\n // but that doesn't work because wasm-pack unconditionally adds\n // \"sideEffects\":false (see below).\n //\n // OTOH, even though it can't be inlined, it should be still reasonably\n // cheap since the requested file is already in cache (it was loaded by\n // the main thread).\n const pkg = await __webpack_require__.e(/*! import() */ \"vendors-node_modules_jsquash_oxipng_codec_pkg-parallel_squoosh_oxipng_js\").then(__webpack_require__.bind(__webpack_require__, /*! ../../../squoosh_oxipng */ \"./node_modules/@jsquash/oxipng/codec/pkg-parallel/squoosh_oxipng.js\"));\n await pkg.default(data.module, data.memory);\n postMessage({ type: 'wasm_bindgen_worker_ready' });\n pkg.wbg_rayon_start_worker(data.receiver);\n});\n\nasync function startWorkers(module, memory, builder) {\n const workerInit = {\n type: 'wasm_bindgen_worker_init',\n module,\n memory,\n receiver: builder.receiver()\n };\n\n try {\n await Promise.all(\n Array.from({ length: builder.numThreads() }, () => {\n // Self-spawn into a new Worker.\n //\n // TODO: while `new URL('...', import.meta.url) becomes a semi-standard\n // way to get asset URLs relative to the module across various bundlers\n // and browser, ideally we should switch to `import.meta.resolve`\n // once it becomes a standard.\n //\n // Note: we could use `../../..` as the URL here to inline workerHelpers.js\n // into the parent entry instead of creating another split point -\n // this would be preferable from optimization perspective -\n // however, Webpack then eliminates all message handler code\n // because wasm-pack produces \"sideEffects\":false in package.json\n // unconditionally.\n //\n // The only way to work around that is to have side effect code\n // in an entry point such as Worker file itself.\n const worker = new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(\"node_modules_jsquash_oxipng_codec_pkg-parallel_snippets_wasm-bindgen-rayon-3d2df09ebec17a22_s-312b0a0\"), __webpack_require__.b), {\n type: undefined\n });\n worker.postMessage(workerInit);\n return waitForMsgType(worker, 'wasm_bindgen_worker_ready');\n })\n );\n builder.build();\n } finally {\n builder.free();\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js?");
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = __webpack_modules__;
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/ensure chunk */
/******/ (() => {
/******/ __webpack_require__.f = {};
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = (chunkId) => {
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
/******/ __webpack_require__.f[key](chunkId, promises);
/******/ return promises;
/******/ }, []));
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/get javascript chunk filename */
/******/ (() => {
/******/ // This function allow to reference async chunks
/******/ __webpack_require__.u = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return "" + chunkId + ".js";
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/publicPath */
/******/ (() => {
/******/ __webpack_require__.p = "/test/wp-content/plugins/squeeze/assets/js/";
/******/ })();
/******/
/******/ /* webpack/runtime/importScripts chunk loading */
/******/ (() => {
/******/ __webpack_require__.b = self.location + "";
/******/
/******/ // object to store loaded chunks
/******/ // "1" means "already loaded"
/******/ var installedChunks = {
/******/ "node_modules_jsquash_oxipng_codec_pkg-parallel_snippets_wasm-bindgen-rayon-3d2df09ebec17a22_s-312b0a0": 1
/******/ };
/******/
/******/ // importScripts chunk loading
/******/ var installChunk = (data) => {
/******/ var [chunkIds, moreModules, runtime] = data;
/******/ for(var moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(runtime) runtime(__webpack_require__);
/******/ while(chunkIds.length)
/******/ installedChunks[chunkIds.pop()] = 1;
/******/ parentChunkLoadingFunction(data);
/******/ };
/******/ __webpack_require__.f.i = (chunkId, promises) => {
/******/ // "1" is the signal for "already loaded"
/******/ if(!installedChunks[chunkId]) {
/******/ if(true) { // all chunks have JS
/******/ importScripts(__webpack_require__.p + __webpack_require__.u(chunkId));
/******/ }
/******/ }
/******/ };
/******/
/******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
/******/ var parentChunkLoadingFunction = chunkLoadingGlobal.push.bind(chunkLoadingGlobal);
/******/ chunkLoadingGlobal.push = installChunk;
/******/
/******/ // no HMR
/******/
/******/ // no HMR manifest
/******/ })();
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module is referenced by other modules so it can't be inlined
/******/ var __webpack_exports__ = __webpack_require__("./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js");
/******/
/******/ })()
;

View File

@ -0,0 +1,184 @@
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js":
/*!***************************************************************************************************************************!*\
!*** ./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js ***!
\***************************************************************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"startWorkers\": () => (/* binding */ startWorkers)\n/* harmony export */ });\n/**\n * Copyright 2021 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Note: we use `wasm_bindgen_worker_`-prefixed message types to make sure\n// we can handle bundling into other files, which might happen to have their\n// own `postMessage`/`onmessage` communication channels.\n//\n// If we didn't take that into the account, we could send much simpler signals\n// like just `0` or whatever, but the code would be less resilient.\n\nfunction waitForMsgType(target, type) {\n return new Promise(resolve => {\n target.addEventListener('message', function onMsg({ data }) {\n if (data == null || data.type !== type) return;\n target.removeEventListener('message', onMsg);\n resolve(data);\n });\n });\n}\n\nwaitForMsgType(self, 'wasm_bindgen_worker_init').then(async data => {\n // # Note 1\n // Our JS should have been generated in\n // `[out-dir]/snippets/wasm-bindgen-rayon-[hash]/workerHelpers.js`,\n // resolve the main module via `../../..`.\n //\n // This might need updating if the generated structure changes on wasm-bindgen\n // side ever in the future, but works well with bundlers today. The whole\n // point of this crate, after all, is to abstract away unstable features\n // and temporary bugs so that you don't need to deal with them in your code.\n //\n // # Note 2\n // This could be a regular import, but then some bundlers complain about\n // circular deps.\n //\n // Dynamic import could be cheap if this file was inlined into the parent,\n // which would require us just using `../../..` in `new Worker` below,\n // but that doesn't work because wasm-pack unconditionally adds\n // \"sideEffects\":false (see below).\n //\n // OTOH, even though it can't be inlined, it should be still reasonably\n // cheap since the requested file is already in cache (it was loaded by\n // the main thread).\n const pkg = await __webpack_require__.e(/*! import() */ \"vendors-node_modules_jsquash_oxipng_codec_pkg-parallel_squoosh_oxipng_js\").then(__webpack_require__.bind(__webpack_require__, /*! ../../../squoosh_oxipng */ \"./node_modules/@jsquash/oxipng/codec/pkg-parallel/squoosh_oxipng.js\"));\n await pkg.default(data.module, data.memory);\n postMessage({ type: 'wasm_bindgen_worker_ready' });\n pkg.wbg_rayon_start_worker(data.receiver);\n});\n\nasync function startWorkers(module, memory, builder) {\n const workerInit = {\n type: 'wasm_bindgen_worker_init',\n module,\n memory,\n receiver: builder.receiver()\n };\n\n try {\n await Promise.all(\n Array.from({ length: builder.numThreads() }, () => {\n // Self-spawn into a new Worker.\n //\n // TODO: while `new URL('...', import.meta.url) becomes a semi-standard\n // way to get asset URLs relative to the module across various bundlers\n // and browser, ideally we should switch to `import.meta.resolve`\n // once it becomes a standard.\n //\n // Note: we could use `../../..` as the URL here to inline workerHelpers.js\n // into the parent entry instead of creating another split point -\n // this would be preferable from optimization perspective -\n // however, Webpack then eliminates all message handler code\n // because wasm-pack produces \"sideEffects\":false in package.json\n // unconditionally.\n //\n // The only way to work around that is to have side effect code\n // in an entry point such as Worker file itself.\n const worker = new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(\"node_modules_jsquash_oxipng_codec_pkg-parallel_snippets_wasm-bindgen-rayon-3d2df09ebec17a22_s-312b0a0\"), __webpack_require__.b), {\n type: undefined\n });\n worker.postMessage(workerInit);\n return waitForMsgType(worker, 'wasm_bindgen_worker_ready');\n })\n );\n builder.build();\n } finally {\n builder.free();\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js?");
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = __webpack_modules__;
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/ensure chunk */
/******/ (() => {
/******/ __webpack_require__.f = {};
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = (chunkId) => {
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
/******/ __webpack_require__.f[key](chunkId, promises);
/******/ return promises;
/******/ }, []));
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/get javascript chunk filename */
/******/ (() => {
/******/ // This function allow to reference async chunks
/******/ __webpack_require__.u = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return "" + chunkId + ".script.bundle.js";
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/global */
/******/ (() => {
/******/ __webpack_require__.g = (function() {
/******/ if (typeof globalThis === 'object') return globalThis;
/******/ try {
/******/ return this || new Function('return this')();
/******/ } catch (e) {
/******/ if (typeof window === 'object') return window;
/******/ }
/******/ })();
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/publicPath */
/******/ (() => {
/******/ var scriptUrl;
/******/ if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + "";
/******/ var document = __webpack_require__.g.document;
/******/ if (!scriptUrl && document) {
/******/ if (document.currentScript)
/******/ scriptUrl = document.currentScript.src;
/******/ if (!scriptUrl) {
/******/ var scripts = document.getElementsByTagName("script");
/******/ if(scripts.length) scriptUrl = scripts[scripts.length - 1].src
/******/ }
/******/ }
/******/ // When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration
/******/ // or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.
/******/ if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");
/******/ scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/");
/******/ __webpack_require__.p = scriptUrl;
/******/ })();
/******/
/******/ /* webpack/runtime/importScripts chunk loading */
/******/ (() => {
/******/ __webpack_require__.b = self.location + "";
/******/
/******/ // object to store loaded chunks
/******/ // "1" means "already loaded"
/******/ var installedChunks = {
/******/ "node_modules_jsquash_oxipng_codec_pkg-parallel_snippets_wasm-bindgen-rayon-3d2df09ebec17a22_s-312b0a0": 1
/******/ };
/******/
/******/ // importScripts chunk loading
/******/ var installChunk = (data) => {
/******/ var [chunkIds, moreModules, runtime] = data;
/******/ for(var moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(runtime) runtime(__webpack_require__);
/******/ while(chunkIds.length)
/******/ installedChunks[chunkIds.pop()] = 1;
/******/ parentChunkLoadingFunction(data);
/******/ };
/******/ __webpack_require__.f.i = (chunkId, promises) => {
/******/ // "1" is the signal for "already loaded"
/******/ if(!installedChunks[chunkId]) {
/******/ if(true) { // all chunks have JS
/******/ importScripts(__webpack_require__.p + __webpack_require__.u(chunkId));
/******/ }
/******/ }
/******/ };
/******/
/******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
/******/ var parentChunkLoadingFunction = chunkLoadingGlobal.push.bind(chunkLoadingGlobal);
/******/ chunkLoadingGlobal.push = installChunk;
/******/
/******/ // no HMR
/******/
/******/ // no HMR manifest
/******/ })();
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module is referenced by other modules so it can't be inlined
/******/ var __webpack_exports__ = __webpack_require__("./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js");
/******/
/******/ })()
;

View File

@ -0,0 +1,22 @@
"use strict";
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
(self["webpackChunk"] = self["webpackChunk"] || []).push([["node_modules_jsquash_oxipng_codec_pkg-parallel_snippets_wasm-bindgen-rayon-3d2df09ebec17a22_s-312b0a1"],{
/***/ "./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js":
/*!***************************************************************************************************************************!*\
!*** ./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js ***!
\***************************************************************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"startWorkers\": () => (/* binding */ startWorkers)\n/* harmony export */ });\n/**\n * Copyright 2021 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Note: we use `wasm_bindgen_worker_`-prefixed message types to make sure\n// we can handle bundling into other files, which might happen to have their\n// own `postMessage`/`onmessage` communication channels.\n//\n// If we didn't take that into the account, we could send much simpler signals\n// like just `0` or whatever, but the code would be less resilient.\n\nfunction waitForMsgType(target, type) {\n return new Promise(resolve => {\n target.addEventListener('message', function onMsg({ data }) {\n if (data == null || data.type !== type) return;\n target.removeEventListener('message', onMsg);\n resolve(data);\n });\n });\n}\n\nwaitForMsgType(self, 'wasm_bindgen_worker_init').then(async data => {\n // # Note 1\n // Our JS should have been generated in\n // `[out-dir]/snippets/wasm-bindgen-rayon-[hash]/workerHelpers.js`,\n // resolve the main module via `../../..`.\n //\n // This might need updating if the generated structure changes on wasm-bindgen\n // side ever in the future, but works well with bundlers today. The whole\n // point of this crate, after all, is to abstract away unstable features\n // and temporary bugs so that you don't need to deal with them in your code.\n //\n // # Note 2\n // This could be a regular import, but then some bundlers complain about\n // circular deps.\n //\n // Dynamic import could be cheap if this file was inlined into the parent,\n // which would require us just using `../../..` in `new Worker` below,\n // but that doesn't work because wasm-pack unconditionally adds\n // \"sideEffects\":false (see below).\n //\n // OTOH, even though it can't be inlined, it should be still reasonably\n // cheap since the requested file is already in cache (it was loaded by\n // the main thread).\n const pkg = await __webpack_require__.e(/*! import() */ \"vendors-node_modules_jsquash_oxipng_codec_pkg-parallel_squoosh_oxipng_js\").then(__webpack_require__.bind(__webpack_require__, /*! ../../../squoosh_oxipng */ \"./node_modules/@jsquash/oxipng/codec/pkg-parallel/squoosh_oxipng.js\"));\n await pkg.default(data.module, data.memory);\n postMessage({ type: 'wasm_bindgen_worker_ready' });\n pkg.wbg_rayon_start_worker(data.receiver);\n});\n\nasync function startWorkers(module, memory, builder) {\n const workerInit = {\n type: 'wasm_bindgen_worker_init',\n module,\n memory,\n receiver: builder.receiver()\n };\n\n try {\n await Promise.all(\n Array.from({ length: builder.numThreads() }, () => {\n // Self-spawn into a new Worker.\n //\n // TODO: while `new URL('...', import.meta.url) becomes a semi-standard\n // way to get asset URLs relative to the module across various bundlers\n // and browser, ideally we should switch to `import.meta.resolve`\n // once it becomes a standard.\n //\n // Note: we could use `../../..` as the URL here to inline workerHelpers.js\n // into the parent entry instead of creating another split point -\n // this would be preferable from optimization perspective -\n // however, Webpack then eliminates all message handler code\n // because wasm-pack produces \"sideEffects\":false in package.json\n // unconditionally.\n //\n // The only way to work around that is to have side effect code\n // in an entry point such as Worker file itself.\n const worker = new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(\"node_modules_jsquash_oxipng_codec_pkg-parallel_snippets_wasm-bindgen-rayon-3d2df09ebec17a22_s-312b0a0\"), __webpack_require__.b), {\n type: undefined\n });\n worker.postMessage(workerInit);\n return waitForMsgType(worker, 'wasm_bindgen_worker_ready');\n })\n );\n builder.build();\n } finally {\n builder.free();\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js?");
/***/ })
}]);

View File

@ -0,0 +1,22 @@
"use strict";
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
(self["webpackChunk"] = self["webpackChunk"] || []).push([["node_modules_jsquash_oxipng_codec_pkg-parallel_snippets_wasm-bindgen-rayon-3d2df09ebec17a22_s-312b0a1"],{
/***/ "./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js":
/*!***************************************************************************************************************************!*\
!*** ./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js ***!
\***************************************************************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"startWorkers\": () => (/* binding */ startWorkers)\n/* harmony export */ });\n/**\n * Copyright 2021 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Note: we use `wasm_bindgen_worker_`-prefixed message types to make sure\n// we can handle bundling into other files, which might happen to have their\n// own `postMessage`/`onmessage` communication channels.\n//\n// If we didn't take that into the account, we could send much simpler signals\n// like just `0` or whatever, but the code would be less resilient.\n\nfunction waitForMsgType(target, type) {\n return new Promise(resolve => {\n target.addEventListener('message', function onMsg({ data }) {\n if (data == null || data.type !== type) return;\n target.removeEventListener('message', onMsg);\n resolve(data);\n });\n });\n}\n\nwaitForMsgType(self, 'wasm_bindgen_worker_init').then(async data => {\n // # Note 1\n // Our JS should have been generated in\n // `[out-dir]/snippets/wasm-bindgen-rayon-[hash]/workerHelpers.js`,\n // resolve the main module via `../../..`.\n //\n // This might need updating if the generated structure changes on wasm-bindgen\n // side ever in the future, but works well with bundlers today. The whole\n // point of this crate, after all, is to abstract away unstable features\n // and temporary bugs so that you don't need to deal with them in your code.\n //\n // # Note 2\n // This could be a regular import, but then some bundlers complain about\n // circular deps.\n //\n // Dynamic import could be cheap if this file was inlined into the parent,\n // which would require us just using `../../..` in `new Worker` below,\n // but that doesn't work because wasm-pack unconditionally adds\n // \"sideEffects\":false (see below).\n //\n // OTOH, even though it can't be inlined, it should be still reasonably\n // cheap since the requested file is already in cache (it was loaded by\n // the main thread).\n const pkg = await __webpack_require__.e(/*! import() */ \"vendors-node_modules_jsquash_oxipng_codec_pkg-parallel_squoosh_oxipng_js\").then(__webpack_require__.bind(__webpack_require__, /*! ../../../squoosh_oxipng */ \"./node_modules/@jsquash/oxipng/codec/pkg-parallel/squoosh_oxipng.js\"));\n await pkg.default(data.module, data.memory);\n postMessage({ type: 'wasm_bindgen_worker_ready' });\n pkg.wbg_rayon_start_worker(data.receiver);\n});\n\nasync function startWorkers(module, memory, builder) {\n const workerInit = {\n type: 'wasm_bindgen_worker_init',\n module,\n memory,\n receiver: builder.receiver()\n };\n\n try {\n await Promise.all(\n Array.from({ length: builder.numThreads() }, () => {\n // Self-spawn into a new Worker.\n //\n // TODO: while `new URL('...', import.meta.url) becomes a semi-standard\n // way to get asset URLs relative to the module across various bundlers\n // and browser, ideally we should switch to `import.meta.resolve`\n // once it becomes a standard.\n //\n // Note: we could use `../../..` as the URL here to inline workerHelpers.js\n // into the parent entry instead of creating another split point -\n // this would be preferable from optimization perspective -\n // however, Webpack then eliminates all message handler code\n // because wasm-pack produces \"sideEffects\":false in package.json\n // unconditionally.\n //\n // The only way to work around that is to have side effect code\n // in an entry point such as Worker file itself.\n const worker = new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(\"node_modules_jsquash_oxipng_codec_pkg-parallel_snippets_wasm-bindgen-rayon-3d2df09ebec17a22_s-312b0a0\"), __webpack_require__.b), {\n type: undefined\n });\n worker.postMessage(workerInit);\n return waitForMsgType(worker, 'wasm_bindgen_worker_ready');\n })\n );\n builder.build();\n } finally {\n builder.free();\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js?");
/***/ })
}]);

View File

@ -0,0 +1,157 @@
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js":
/*!***************************************************************************************************************************!*\
!*** ./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js ***!
\***************************************************************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"startWorkers\": () => (/* binding */ startWorkers)\n/* harmony export */ });\n/**\n * Copyright 2021 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Note: we use `wasm_bindgen_worker_`-prefixed message types to make sure\n// we can handle bundling into other files, which might happen to have their\n// own `postMessage`/`onmessage` communication channels.\n//\n// If we didn't take that into the account, we could send much simpler signals\n// like just `0` or whatever, but the code would be less resilient.\n\nfunction waitForMsgType(target, type) {\n return new Promise(resolve => {\n target.addEventListener('message', function onMsg({ data }) {\n if (data == null || data.type !== type) return;\n target.removeEventListener('message', onMsg);\n resolve(data);\n });\n });\n}\n\nwaitForMsgType(self, 'wasm_bindgen_worker_init').then(async data => {\n // # Note 1\n // Our JS should have been generated in\n // `[out-dir]/snippets/wasm-bindgen-rayon-[hash]/workerHelpers.js`,\n // resolve the main module via `../../..`.\n //\n // This might need updating if the generated structure changes on wasm-bindgen\n // side ever in the future, but works well with bundlers today. The whole\n // point of this crate, after all, is to abstract away unstable features\n // and temporary bugs so that you don't need to deal with them in your code.\n //\n // # Note 2\n // This could be a regular import, but then some bundlers complain about\n // circular deps.\n //\n // Dynamic import could be cheap if this file was inlined into the parent,\n // which would require us just using `../../..` in `new Worker` below,\n // but that doesn't work because wasm-pack unconditionally adds\n // \"sideEffects\":false (see below).\n //\n // OTOH, even though it can't be inlined, it should be still reasonably\n // cheap since the requested file is already in cache (it was loaded by\n // the main thread).\n const pkg = await __webpack_require__.e(/*! import() */ \"node_modules_jsquash_oxipng_codec_pkg-parallel_squoosh_oxipng_js\").then(__webpack_require__.bind(__webpack_require__, /*! ../../../squoosh_oxipng */ \"./node_modules/@jsquash/oxipng/codec/pkg-parallel/squoosh_oxipng.js\"));\n await pkg.default(data.module, data.memory);\n postMessage({ type: 'wasm_bindgen_worker_ready' });\n pkg.wbg_rayon_start_worker(data.receiver);\n});\n\nasync function startWorkers(module, memory, builder) {\n const workerInit = {\n type: 'wasm_bindgen_worker_init',\n module,\n memory,\n receiver: builder.receiver()\n };\n\n try {\n await Promise.all(\n Array.from({ length: builder.numThreads() }, () => {\n // Self-spawn into a new Worker.\n //\n // TODO: while `new URL('...', import.meta.url) becomes a semi-standard\n // way to get asset URLs relative to the module across various bundlers\n // and browser, ideally we should switch to `import.meta.resolve`\n // once it becomes a standard.\n //\n // Note: we could use `../../..` as the URL here to inline workerHelpers.js\n // into the parent entry instead of creating another split point -\n // this would be preferable from optimization perspective -\n // however, Webpack then eliminates all message handler code\n // because wasm-pack produces \"sideEffects\":false in package.json\n // unconditionally.\n //\n // The only way to work around that is to have side effect code\n // in an entry point such as Worker file itself.\n const worker = new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(\"node_modules_jsquash_oxipng_codec_pkg-parallel_snippets_wasm-bindgen-rayon-3d2df09ebec17a22_s-3a2b7f\"), __webpack_require__.b), {\n type: undefined\n });\n worker.postMessage(workerInit);\n return waitForMsgType(worker, 'wasm_bindgen_worker_ready');\n })\n );\n builder.build();\n } finally {\n builder.free();\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js?");
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = __webpack_modules__;
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/ensure chunk */
/******/ (() => {
/******/ __webpack_require__.f = {};
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = (chunkId) => {
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
/******/ __webpack_require__.f[key](chunkId, promises);
/******/ return promises;
/******/ }, []));
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/get javascript chunk filename */
/******/ (() => {
/******/ // This function allow to reference async chunks
/******/ __webpack_require__.u = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return "" + chunkId + ".script.bundle.js";
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/publicPath */
/******/ (() => {
/******/ __webpack_require__.p = "";
/******/ })();
/******/
/******/ /* webpack/runtime/importScripts chunk loading */
/******/ (() => {
/******/ __webpack_require__.b = self.location + "";
/******/
/******/ // object to store loaded chunks
/******/ // "1" means "already loaded"
/******/ var installedChunks = {
/******/ "node_modules_jsquash_oxipng_codec_pkg-parallel_snippets_wasm-bindgen-rayon-3d2df09ebec17a22_s-3a2b7f": 1
/******/ };
/******/
/******/ // importScripts chunk loading
/******/ var installChunk = (data) => {
/******/ var [chunkIds, moreModules, runtime] = data;
/******/ for(var moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(runtime) runtime(__webpack_require__);
/******/ while(chunkIds.length)
/******/ installedChunks[chunkIds.pop()] = 1;
/******/ parentChunkLoadingFunction(data);
/******/ };
/******/ __webpack_require__.f.i = (chunkId, promises) => {
/******/ // "1" is the signal for "already loaded"
/******/ if(!installedChunks[chunkId]) {
/******/ if(true) { // all chunks have JS
/******/ importScripts(__webpack_require__.p + __webpack_require__.u(chunkId));
/******/ }
/******/ }
/******/ };
/******/
/******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
/******/ var parentChunkLoadingFunction = chunkLoadingGlobal.push.bind(chunkLoadingGlobal);
/******/ chunkLoadingGlobal.push = installChunk;
/******/
/******/ // no HMR
/******/
/******/ // no HMR manifest
/******/ })();
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module is referenced by other modules so it can't be inlined
/******/ var __webpack_exports__ = __webpack_require__("./node_modules/@jsquash/oxipng/codec/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js");
/******/
/******/ })()
;

View File

@ -0,0 +1,32 @@
"use strict";
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
(self["webpackChunk"] = self["webpackChunk"] || []).push([["node_modules_jsquash_oxipng_codec_pkg_squoosh_oxipng_js"],{
/***/ "./node_modules/@jsquash/oxipng/codec/pkg/squoosh_oxipng_bg.wasm":
/*!***********************************************************************!*\
!*** ./node_modules/@jsquash/oxipng/codec/pkg/squoosh_oxipng_bg.wasm ***!
\***********************************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
eval("module.exports = __webpack_require__.p + \"c96242667dc8e630897a.wasm\";\n\n//# sourceURL=webpack:///./node_modules/@jsquash/oxipng/codec/pkg/squoosh_oxipng_bg.wasm?");
/***/ }),
/***/ "./node_modules/@jsquash/oxipng/codec/pkg/squoosh_oxipng.js":
/*!******************************************************************!*\
!*** ./node_modules/@jsquash/oxipng/codec/pkg/squoosh_oxipng.js ***!
\******************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"optimise\": () => (/* binding */ optimise)\n/* harmony export */ });\n\nlet wasm;\n\nlet cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\n\ncachedTextDecoder.decode();\n\nlet cachegetUint8Memory0 = null;\nfunction getUint8Memory0() {\n if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {\n cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);\n }\n return cachegetUint8Memory0;\n}\n\nfunction getStringFromWasm0(ptr, len) {\n return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));\n}\n\nlet WASM_VECTOR_LEN = 0;\n\nfunction passArray8ToWasm0(arg, malloc) {\n const ptr = malloc(arg.length * 1);\n getUint8Memory0().set(arg, ptr / 1);\n WASM_VECTOR_LEN = arg.length;\n return ptr;\n}\n\nlet cachegetInt32Memory0 = null;\nfunction getInt32Memory0() {\n if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {\n cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);\n }\n return cachegetInt32Memory0;\n}\n\nfunction getArrayU8FromWasm0(ptr, len) {\n return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);\n}\n/**\n* @param {Uint8Array} data\n* @param {number} level\n* @param {boolean} interlace\n* @returns {Uint8Array}\n*/\nfunction optimise(data, level, interlace) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);\n var len0 = WASM_VECTOR_LEN;\n wasm.optimise(retptr, ptr0, len0, level, interlace);\n var r0 = getInt32Memory0()[retptr / 4 + 0];\n var r1 = getInt32Memory0()[retptr / 4 + 1];\n var v1 = getArrayU8FromWasm0(r0, r1).slice();\n wasm.__wbindgen_free(r0, r1 * 1);\n return v1;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n}\n\nasync function load(module, imports) {\n if (typeof Response === 'function' && module instanceof Response) {\n if (typeof WebAssembly.instantiateStreaming === 'function') {\n try {\n return await WebAssembly.instantiateStreaming(module, imports);\n\n } catch (e) {\n if (module.headers.get('Content-Type') != 'application/wasm') {\n console.warn(\"`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n\", e);\n\n } else {\n throw e;\n }\n }\n }\n\n const bytes = await module.arrayBuffer();\n return await WebAssembly.instantiate(bytes, imports);\n\n } else {\n const instance = await WebAssembly.instantiate(module, imports);\n\n if (instance instanceof WebAssembly.Instance) {\n return { instance, module };\n\n } else {\n return instance;\n }\n }\n}\n\nasync function init(input) {\n if (typeof input === 'undefined') {\n input = new URL(/* asset import */ __webpack_require__(/*! squoosh_oxipng_bg.wasm */ \"./node_modules/@jsquash/oxipng/codec/pkg/squoosh_oxipng_bg.wasm\"), __webpack_require__.b);\n }\n const imports = {};\n imports.wbg = {};\n imports.wbg.__wbindgen_throw = function(arg0, arg1) {\n throw new Error(getStringFromWasm0(arg0, arg1));\n };\n\n if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {\n input = fetch(input);\n }\n\n\n\n const { instance, module } = await load(await input, imports);\n\n wasm = instance.exports;\n init.__wbindgen_wasm_module = module;\n\n return wasm;\n}\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (init);\n\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/oxipng/codec/pkg/squoosh_oxipng.js?");
/***/ })
}]);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,337 @@
//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')

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,104 @@
import * as jpeg from '@jsquash/jpeg';
import * as png from '@jsquash/png';
import optimise from '@jsquash/oxipng/optimise';
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 = {
"jpeg_quality": 75,
"jpeg_baseline": false,
"jpeg_arithmetic": false,
"jpeg_progressive": true,
"jpeg_optimize_coding": true,
"jpeg_smoothing": 0,
"jpeg_color_space": 3,
"jpeg_quant_table": 3,
"jpeg_trellis_multipass": false,
"jpeg_trellis_opt_zero": false,
"jpeg_trellis_opt_table": false,
"jpeg_trellis_loops": 1,
"jpeg_auto_subsample": true,
"jpeg_chroma_subsample": 2,
"jpeg_separate_chroma_quality": false,
"jpeg_chroma_quality": 75,
"png_level": 2,
"png_interlace": false,
"auto_compress": true,
"backup_original": true
};
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;
}
self.onmessage = async function(e) {
console.log('Worker: Message received from main script');
const {fileBuffer, sourceType, outputType} = e.data;
let imageBuffer = await convert(sourceType, outputType, fileBuffer);
let base64 = await showOutput(imageBuffer, outputType);
console.log(e)
postMessage(base64)
}

View File

@ -0,0 +1,33 @@
{
"translation-revision-date": "2023-06-13 18:58+0300",
"generator": "WP-CLI\/2.6.0",
"source": "assets\/js\/script.js",
"domain": "messages",
"locale_data": {
"messages": {
"": {
"domain": "messages",
"lang": "uk",
"plural-forms": "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);"
},
"Compressed successfully, updating...": [
"\u0423\u0441\u043f\u0456\u0448\u043d\u043e \u0441\u0442\u0438\u0441\u043d\u0443\u0442\u043e, \u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f..."
],
"An error has occured. Check the console for details.": [
"\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430. \u0417\u0432\u0435\u0440\u043d\u0456\u0442\u044c\u0441\u044f \u0434\u043e \u043a\u043e\u043d\u0441\u043e\u043b\u0456 \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c."
],
"Updated successfully": [
"\u041e\u043d\u043e\u0432\u043b\u0435\u043d\u043e \u0443\u0441\u043f\u0456\u0448\u043d\u043e"
],
"All images have been compressed!": [
"\u0412\u0441\u0456 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u0438 \u0441\u0442\u0438\u0441\u043d\u0443\u0442\u0456!"
],
"Restore in process...": [
"\u0412\u0456\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0456..."
],
"Compressing...": [
"\u0421\u0442\u0438\u0441\u043a\u0430\u0454\u043c\u043e..."
]
}
}
}

View File

@ -0,0 +1,33 @@
{
"translation-revision-date": "2023-06-13 18:58+0300",
"generator": "WP-CLI\/2.6.0",
"source": "assets\/js\/script.bundle.js",
"domain": "messages",
"locale_data": {
"messages": {
"": {
"domain": "messages",
"lang": "uk",
"plural-forms": "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);"
},
"Compressed successfully, updating...": [
"\u0423\u0441\u043f\u0456\u0448\u043d\u043e \u0441\u0442\u0438\u0441\u043d\u0443\u0442\u043e, \u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f..."
],
"An error has occured. Check the console for details.": [
"\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430. \u0417\u0432\u0435\u0440\u043d\u0456\u0442\u044c\u0441\u044f \u0434\u043e \u043a\u043e\u043d\u0441\u043e\u043b\u0456 \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c."
],
"Updated successfully": [
"\u041e\u043d\u043e\u0432\u043b\u0435\u043d\u043e \u0443\u0441\u043f\u0456\u0448\u043d\u043e"
],
"All images have been compressed!": [
"\u0412\u0441\u0456 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u0438 \u0441\u0442\u0438\u0441\u043d\u0443\u0442\u0456!"
],
"Restore in process...": [
"\u0412\u0456\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0456..."
],
"Compressing...": [
"\u0421\u0442\u0438\u0441\u043a\u0430\u0454\u043c\u043e..."
]
}
}
}

Binary file not shown.

View File

@ -0,0 +1,252 @@
# Copyright (C) 2023 Bogdan Bendziukov
# This file is distributed under the GNU GPL v3.
msgid ""
msgstr ""
"Project-Id-Version: Squeeze 1.0\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/squeeze\n"
"POT-Creation-Date: 2023-05-23T15:32:49+00:00\n"
"PO-Revision-Date: 2023-06-13 18:58+0300\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: uk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
"X-Generator: Poedit 3.1.1\n"
"X-Domain: squeeze\n"
#. Plugin Name of the plugin
#: src/settings.php:14 src/settings.php:15
msgid "Squeeze"
msgstr ""
#. Description of the plugin
msgid "Compress images by squoosh.app"
msgstr "Стискайте зображення за допомогою squoosh.app"
#. Author of the plugin
msgid "Bogdan Bendziukov"
msgstr "Богдан Бендзюков"
#. Author URI of the plugin
msgid "https://bogdan.kyiv.ua"
msgstr ""
#: src/handlers.php:40
msgid "Backup original image failed"
msgstr "Не вдалося створити резервну копію оригінального зображення"
#: src/handlers.php:48
msgid "Upload image failed"
msgstr "Не вдалося завантажити зображення"
#: src/handlers.php:65
msgid "Compressed successfully"
msgstr "Компресія успішна"
#: src/handlers.php:67 src/handlers.php:107
msgid "Attachment not updated"
msgstr "Вкладення не оновлено"
#: src/handlers.php:90
msgid "Restore original image failed"
msgstr "Відновлення оригінального зображення не вдалося"
#: src/handlers.php:105
msgid "Restored successfully"
msgstr "Відновлено успішно"
#: src/handlers.php:112 src/handlers.php:137
msgid "Attachment not found"
msgstr "Вкладення не знайдено"
#: src/settings.php:29
msgid "Bulk Compress With Squeeze"
msgstr "Комплексне стиснення із Squeeze"
#: src/settings.php:30
msgid "Squeeze Bulk"
msgstr "Комплексне стиснення"
#: src/settings.php:80
msgid "This page allows you to compress all images in your media library."
msgstr "Ця сторінка дозволяє стиснути всі зображення у вашій медіатеці."
#: src/settings.php:81
msgid "Do not close this page during the compressing process."
msgstr "Не закривайте цю сторінку під час процесу стиснення."
#: src/settings.php:82
msgid ""
"Please note that this process may take a long time depending on the number "
"of images in your library."
msgstr ""
"Зверніть увагу, що цей процес може зайняти багато часу, залежно від "
"кількості зображень у вашій бібліотеці."
#: src/settings.php:85
msgid "All images in your media library are compressed."
msgstr "Усі зображення у вашій медіатеці стиснуті."
#: src/settings.php:87
msgid ""
"You have <strong>%s</strong> uncompressed JPG/PNG images from total <strong>"
"%s</strong> JPG/PNG images in your media library."
msgstr ""
"У вашій медіатеці є <strong>%s</strong> нестиснутих зображень JPG/PNG із "
"загальної кількості <strong>%s</strong> зображень JPG/PNG."
#: src/settings.php:161
msgid "Basic Settings"
msgstr "Основні налаштування"
#: src/settings.php:163
msgid "Auto compress"
msgstr "Автоматичне стиснення"
#: src/settings.php:165
msgid "Backup original image"
msgstr "Створити резервну копію оригінального зображення"
#: src/settings.php:167
msgid "JPEG Settings"
msgstr "Налаштування JPEG"
#: src/settings.php:169
msgid "Quality"
msgstr "Якість"
#: src/settings.php:170
msgid "Pointless spec compliance"
msgstr ""
#: src/settings.php:171
msgid "Arithmetic"
msgstr ""
#: src/settings.php:172
msgid "Progressive rendering"
msgstr ""
#: src/settings.php:173
msgid "Optimize Huffman table"
msgstr ""
#: src/settings.php:174
msgid "Smoothing"
msgstr ""
#: src/settings.php:175
msgid "Channels"
msgstr ""
#: src/settings.php:176
msgid "Quantization"
msgstr ""
#: src/settings.php:187
msgid "Trellis multipass"
msgstr ""
#: src/settings.php:188
msgid "Optimize zero block runs"
msgstr ""
#: src/settings.php:189
msgid "Optimize after trellis quantization"
msgstr ""
#: src/settings.php:190
msgid "Trellis quantization passes"
msgstr ""
#: src/settings.php:191
msgid "Auto subsample chroma"
msgstr ""
#: src/settings.php:192
msgid "Subsample chroma by"
msgstr ""
#: src/settings.php:193
msgid "Separate chroma quality"
msgstr ""
#: src/settings.php:194
msgid "Chroma quality"
msgstr ""
#: src/settings.php:196
msgid "PNG Settings"
msgstr "Налаштування PNG"
#: src/settings.php:198
msgid "Effort"
msgstr ""
#: src/settings.php:199
msgid "Interlace"
msgstr ""
#: src/settings.php:230
msgid "Settings have been updated."
msgstr "Налаштування було оновлено."
#: src/settings.php:329
msgid "Basic options"
msgstr "Базові опції"
#: src/settings.php:332
msgid "Compress settings for JPEG images using MozJPEG encoder"
msgstr "Налаштування стиснення зображень JPEG за допомогою кодера MozJPEG"
#: src/settings.php:335
msgid "Compress settings for PNG images using OxiPNG encoder"
msgstr "Налаштування стиснення зображень PNG за допомогою кодера OxiPNG"
#: src/settings.php:365
msgid "Settings have been restored."
msgstr "Налаштування відновлено."
#: src/settings.php:386
msgid "Compressed"
msgstr "Стиснуто"
#: src/settings.php:387
msgid "Restore original"
msgstr "Відновити оригінальне зображення"
#: src/settings.php:389
msgid "Not compressed"
msgstr "Не стиснуто"
#: src/settings.php:390
msgid "Compress"
msgstr "Стиснути"
#: assets/js/script.bundle.js:19 assets/js/script.js:159
msgid "Compressed successfully, updating..."
msgstr "Успішно стиснуто, оновлення..."
#: assets/js/script.bundle.js:19 assets/js/script.js:164
#: assets/js/script.js:253
msgid "An error has occured. Check the console for details."
msgstr "Виникла помилка. Зверніться до консолі для отримання подробиць."
#: assets/js/script.bundle.js:19 assets/js/script.js:172
msgid "Updated successfully"
msgstr "Оновлено успішно"
#: assets/js/script.bundle.js:19 assets/js/script.js:198
msgid "All images have been compressed!"
msgstr "Всі зображення були стиснуті!"
#: assets/js/script.bundle.js:19 assets/js/script.js:249
msgid "Restore in process..."
msgstr "Відновлення в процесі..."
#: assets/js/script.bundle.js:19 assets/js/script.js:292
msgid "Compressing..."
msgstr "Стискаємо..."

View File

@ -0,0 +1,242 @@
# Copyright (C) 2023 Bogdan Bendziukov
# This file is distributed under the GNU GPL v3.
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Squeeze 1.0\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/squeeze\n"
"POT-Creation-Date: 2023-06-13 18:57+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.1.1\n"
"X-Domain: squeeze\n"
#. Plugin Name of the plugin
#: src/settings.php:14
msgid "Squeeze"
msgstr ""
#. Description of the plugin
msgid "Compress images by squoosh.app"
msgstr ""
#. Author of the plugin
msgid "Bogdan Bendziukov"
msgstr ""
#. Author URI of the plugin
msgid "https://bogdan.kyiv.ua"
msgstr ""
#: src/handlers.php:40
msgid "Backup original image failed"
msgstr ""
#: src/handlers.php:48
msgid "Upload image failed"
msgstr ""
#: src/handlers.php:65
msgid "Compressed successfully"
msgstr ""
#: src/handlers.php:67 src/handlers.php:107
msgid "Attachment not updated"
msgstr ""
#: src/handlers.php:90
msgid "Restore original image failed"
msgstr ""
#: src/handlers.php:105
msgid "Restored successfully"
msgstr ""
#: src/handlers.php:112 src/handlers.php:137
msgid "Attachment not found"
msgstr ""
#: src/settings.php:29
msgid "Bulk Compress With Squeeze"
msgstr ""
#: src/settings.php:30
msgid "Squeeze Bulk"
msgstr ""
#: src/settings.php:80
msgid "This page allows you to compress all images in your media library."
msgstr ""
#: src/settings.php:81
msgid "Do not close this page during the compressing process."
msgstr ""
#: src/settings.php:82
msgid "Please note that this process may take a long time depending on the number of images in your library."
msgstr ""
#: src/settings.php:85
msgid "All images in your media library are compressed."
msgstr ""
#: src/settings.php:87
msgid "You have <strong>%s</strong> uncompressed JPG/PNG images from total <strong>%s</strong> JPG/PNG images in your media library."
msgstr ""
#: src/settings.php:161
msgid "Basic Settings"
msgstr ""
#: src/settings.php:163
msgid "Auto compress"
msgstr ""
#: src/settings.php:165
msgid "Backup original image"
msgstr ""
#: src/settings.php:167
msgid "JPEG Settings"
msgstr ""
#: src/settings.php:169
msgid "Quality"
msgstr ""
#: src/settings.php:170
msgid "Pointless spec compliance"
msgstr ""
#: src/settings.php:171
msgid "Arithmetic"
msgstr ""
#: src/settings.php:172
msgid "Progressive rendering"
msgstr ""
#: src/settings.php:173
msgid "Optimize Huffman table"
msgstr ""
#: src/settings.php:174
msgid "Smoothing"
msgstr ""
#: src/settings.php:175
msgid "Channels"
msgstr ""
#: src/settings.php:176
msgid "Quantization"
msgstr ""
#: src/settings.php:187
msgid "Trellis multipass"
msgstr ""
#: src/settings.php:188
msgid "Optimize zero block runs"
msgstr ""
#: src/settings.php:189
msgid "Optimize after trellis quantization"
msgstr ""
#: src/settings.php:190
msgid "Trellis quantization passes"
msgstr ""
#: src/settings.php:191
msgid "Auto subsample chroma"
msgstr ""
#: src/settings.php:192
msgid "Subsample chroma by"
msgstr ""
#: src/settings.php:193
msgid "Separate chroma quality"
msgstr ""
#: src/settings.php:194
msgid "Chroma quality"
msgstr ""
#: src/settings.php:196
msgid "PNG Settings"
msgstr ""
#: src/settings.php:198
msgid "Effort"
msgstr ""
#: src/settings.php:199
msgid "Interlace"
msgstr ""
#: src/settings.php:230
msgid "Settings have been updated."
msgstr ""
#: src/settings.php:329
msgid "Basic options"
msgstr ""
#: src/settings.php:332
msgid "Compress settings for JPEG images using MozJPEG encoder"
msgstr ""
#: src/settings.php:335
msgid "Compress settings for PNG images using OxiPNG encoder"
msgstr ""
#: src/settings.php:365
msgid "Settings have been restored."
msgstr ""
#: src/settings.php:386
msgid "Compressed"
msgstr ""
#: src/settings.php:387
msgid "Restore original"
msgstr ""
#: src/settings.php:389
msgid "Not compressed"
msgstr ""
#: src/settings.php:390
msgid "Compress"
msgstr ""
#: assets/js/script.bundle.js:19 assets/js/script.js:159
msgid "Compressed successfully, updating..."
msgstr ""
#: assets/js/script.bundle.js:19 assets/js/script.js:164
#: assets/js/script.js:253
msgid "An error has occured. Check the console for details."
msgstr ""
#: assets/js/script.bundle.js:19 assets/js/script.js:172
msgid "Updated successfully"
msgstr ""
#: assets/js/script.bundle.js:19 assets/js/script.js:198
msgid "All images have been compressed!"
msgstr ""
#: assets/js/script.bundle.js:19 assets/js/script.js:249
msgid "Restore in process..."
msgstr ""
#: assets/js/script.bundle.js:19 assets/js/script.js:292
msgid "Compressing..."
msgstr ""

View File

@ -0,0 +1,77 @@
=== Squeeze ===
Contributors: barb0ss
Tags: compress, image, optimise, compression, bulk, optimisation
Requires at least: 6.0
Tested up to: 6.2.2
Requires PHP: 7.0
Stable tag: 1.2
License: GNU GPL v3 or later
License URI: https://www.gnu.org/licenses/gpl-3.0.html
The Squeeze plugin for WordPress allows you to easily optimize and compress images on your website using the [Squoosh.app](https://squoosh.app) service. Squoosh.app is a powerful online tool for image compression, providing excellent image quality while reducing file sizes.
== Description ==
**This is NOT official Squoosh.app plugin. It only uses squoosh.app compression scripts.**
This plugin uses [Squoosh.app](https://squoosh.app) compression scripts, allowing you to compress images directly from your WordPress media library or during the image upload process. By compressing your images, you can improve your website\'s performance, reduce bandwidth usage, and enhance the overall user experience.
== Features ==
* Image Compression: Automatically compresses images in your WordPress media library using Squoosh.app\'s advanced compression algorithms.
* Upload Optimization: Compresses images on-the-fly during the upload process, ensuring optimized images are added to your media library.
* Bulk Compression: Allows you to compress multiple images at once.
* Selective Compression: Choose which images to compress based on your preferences and requirements.
* Custom Compression Settings: Adjust compression parameters such as quality, resizing, and format options to suit your specific needs.
* Restore Option: Provides a restore option to use backup file to restore compressed image to the original image.
== Installation ==
1. Download the plugin ZIP file from the WordPress Plugin Directory, or install the plugin via the WordPress plugin installer.
2. Extract the ZIP file (if downloaded from WordPress Plugin Directory).
3. Upload the plugin folder to the wp-content/plugins/ directory of your WordPress installation.
4. Activate the Squeeze plugin from the WordPress plugins dashboard.
== Frequently Asked Questions ==
= How does the plugin work? =
The plugin uses Squoosh.app's compression algorithms and provides you with the ability to compress images in your WordPress media library or during the image upload process.
= Why should I use image compression on my website? =
Image compression helps improve your website's performance by reducing the file size of images without significantly impacting their quality. Smaller image files load faster, resulting in faster page load times and a better user experience. Additionally, compressed images consume less bandwidth, which can be beneficial for websites with limited hosting resources or mobile users with limited data plans.
= Which image formats does the Squeeze plugin work with? =
Currently, the Squeeze plugin supports JPG and PNG image formats. More formats are about to be added.
= Can I compress multiple images at once? =
Yes, the plugin provides a bulk compression feature. This saves time and effort compared to compressing images individually.
= Can I customize the compression settings? =
Yes, the plugin allows you to customize various compression settings according to your preferences. It supports the same options as Squoosh.app provides.
= How can I test compression settings before upload my images to the media library? =
You can test different options directly on [Squoosh.app](https://squoosh.app). For JPG images select MozJPEG encoder, for PNG images choose OxiPNG.
== Screenshots ==
1. Squeeze Settings
2. Squeeze Bulk Compression Page
3. Squeeze Restore Option
4. Non-optimised image
5. Optimised image with Squeeze Plugin
== Changelog ==
= 1.2 =
* Fix minor bug in Media library
= 1.1 =
* Fix PNG compressor
= 1.0 =
* First release.
== Upgrade Notice ==
= 1.2 =
* Fix minor bug in Media library
= 1.1 =
* Fix PNG compressor
= 1.0 =
* First release.

View File

@ -0,0 +1,92 @@
<?php
/**
* Plugin Name: Squeeze
* Description: Compress images by squoosh.app
* Author URI: https://bogdan.kyiv.ua
* Author: Bogdan Bendziukov
* Version: 1.2
*
* Text Domain: squeeze
* Domain Path: /languages
*
* License: GNU GPL v3
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
*
* Network: false
*
*/
// Exit if accessed directly.
if (!defined('ABSPATH')) {
exit;
}
define('SQUEEZE_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('SQUEEZE_PLUGIN_URL', plugin_dir_url(__FILE__));
add_action('plugins_loaded', 'squeeze_load_textdomain');
/**
* Load plugin textdomain
*/
function squeeze_load_textdomain() {
load_plugin_textdomain('squeeze', false, dirname(plugin_basename(__FILE__)) . '/languages/');
}
include_once(SQUEEZE_PLUGIN_DIR . 'src/settings.php');
include_once(SQUEEZE_PLUGIN_DIR . 'src/handlers.php');
add_action('admin_print_footer_scripts', 'squeeze_block_assets');
/**
* Enqueue assets
*/
function squeeze_block_assets() {
global $pagenow;
$options = get_option( 'squeeze_options' );
$default_options = squeeze_get_default_value( null, true); // get all default values
$js_options = array();
foreach ($default_options as $key => $value) {
if (isset($options[$key])) {
if (is_numeric($options[$key])) {
$js_options[$key] = intval($options[$key]);
} elseif ($options[$key] === "on") {
$js_options[$key] = true;
}
} else {
$js_options[$key] = $value;
}
}
// Enqueue script for backend.
wp_enqueue_script(
'squeeze-script',
// Handle.
plugins_url('/assets/js/script.bundle.js', __FILE__),
array('jquery', 'wp-mediaelement'),
// Dependencies, defined above.
null,
true // Enqueue the script in the footer.
);
// WP Localized globals. Use dynamic PHP stuff in JavaScript via `squeeze` object.
wp_localize_script(
'squeeze-script',
'squeeze',
// Array containing dynamic data for a JS Global.
[
'pluginUrl' => SQUEEZE_PLUGIN_URL,
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('squeeze-nonce'),
'options' => json_encode($js_options),
]
);
wp_set_script_translations('squeeze-script', 'squeeze', plugin_dir_path(__DIR__) . 'languages');
}

View File

@ -0,0 +1,155 @@
<?php
// Exit if accessed directly.
if (!defined('ABSPATH')) {
exit;
}
add_action('wp_ajax_squeeze_update_attachment', 'squeeze_update_attachment');
/**
* Update attachment with compressed image
* https://gist.github.com/cyberwani/ad5452b040001878d692c3165836ebff
*/
function squeeze_update_attachment() {
check_ajax_referer( 'squeeze-nonce', '_ajax_nonce' );
if (isset($_POST["base64"]) && !empty($_POST["base64"])) {
$base64 = sanitize_text_field($_POST["base64"]);
$file_format = sanitize_text_field($_POST["format"]);
$filename = sanitize_file_name($_POST["filename"]);
$attach_id = (int) $_POST["attachmentID"];
$url = sanitize_url($_POST["url"]);
$options = get_option( 'squeeze_options' );
$is_backup_original = isset($options['backup_original']) ? $options['backup_original'] : squeeze_get_default_value('backup_original');
// Upload dir.
$upload_dir = str_replace($filename, "", get_attached_file($attach_id)); // get upload dir from attachment path
$upload_path = str_replace('/', DIRECTORY_SEPARATOR, $upload_dir) . DIRECTORY_SEPARATOR;
$img = str_replace('data:image/'.$file_format.';base64,', '', $base64);
$img = str_replace(' ', '+', $img);
$decoded = base64_decode($img);
if ($is_backup_original) {
// backup original
$backup_filename = preg_replace("/(\.(?!.*\.))/", '.bak.', $filename); // add .bak. before extension
$upload_backup_file = copy($upload_path . $filename, $upload_path . $backup_filename);
if (!$upload_backup_file) {
wp_send_json_error(__('Backup original image failed', 'squeeze'));
}
}
// Save the image in the uploads directory.
$upload_file = file_put_contents($upload_path . $filename, $decoded);
if (!$upload_file) {
wp_send_json_error(__('Upload image failed', 'squeeze'));
}
// Make sure that this file is included, as wp_generate_attachment_metadata() depends on it.
if ( ! function_exists( 'wp_crop_image' ) ) {
require_once(ABSPATH . 'wp-admin/includes/image.php');
}
// Generate the metadata for the attachment, and update the database record.
//$attach_data = wp_generate_attachment_metadata($attach_id, $upload_dir . '/' . $filename);
// create thumbnails from COMPRESSED original image
$attach_data = wp_create_image_subsizes($upload_dir . '/' . $filename, $attach_id);
$is_update_attachment = update_post_meta($attach_id, "squeeze_is_compressed", true);
if ($is_update_attachment) {
wp_send_json_success(__('Compressed successfully', 'squeeze'));
} else {
wp_send_json_error(__('Attachment not updated', 'squeeze'));
}
}
wp_die();
}
add_action('wp_ajax_squeeze_restore_attachment', 'squeeze_restore_attachment');
/**
* Restore original attachment
*/
function squeeze_restore_attachment() {
check_ajax_referer( 'squeeze-nonce', '_ajax_nonce' );
if (isset($_POST["attachmentID"]) && !empty($_POST["attachmentID"]) && wp_get_attachment_url($_POST["attachmentID"])) {
$attach_id = (int) $_POST["attachmentID"];
$can_restore = squeeze_can_restore($attach_id);
if ($can_restore) {
$original_img_path = wp_get_original_image_path($attach_id);
$backup_img_path = preg_replace("/(\.(?!.*\.))/", '.bak.', $original_img_path);
$upload_restore_file = copy($backup_img_path, $original_img_path);
if (!$upload_restore_file) {
wp_send_json_error(__('Restore original image failed', 'squeeze'));
}
// Make sure that this file is included, as wp_generate_attachment_metadata() depends on it.
if ( ! function_exists( 'wp_crop_image' ) ) {
require_once(ABSPATH . 'wp-admin/includes/image.php');
}
// create thumbnails from original image
$attach_data = wp_create_image_subsizes($original_img_path, $attach_id);
$is_update_attachment = delete_post_meta($attach_id, "squeeze_is_compressed");
if ($is_update_attachment) {
unlink($backup_img_path); // delete backup file
wp_send_json_success(__('Restored successfully', 'squeeze'));
} else {
wp_send_json_error(__('Attachment not updated', 'squeeze'));
}
}
} else {
wp_send_json_error(__('Attachment not found', 'squeeze'));
}
wp_die();
}
add_action('wp_ajax_squeeze_get_attachment', 'squeeze_get_attachment');
/**
* Get attachment data
*/
function squeeze_get_attachment() {
check_ajax_referer( 'squeeze-nonce', '_ajax_nonce' );
if (isset($_POST["attachmentID"]) && !empty($_POST["attachmentID"]) && wp_get_attachment_url($_POST["attachmentID"])) {
$attach_id = (int) $_POST["attachmentID"];
$attach_data = array(
'id' => $attach_id,
'url' => wp_get_attachment_url($attach_id),
'mime' => get_post_mime_type($attach_id),
'name' => get_the_title($attach_id),
'filename' => basename( get_attached_file( $attach_id ) ),
);
wp_send_json_success($attach_data);
} else {
wp_send_json_error(__('Attachment not found', 'squeeze'));
}
wp_die();
}
/**
* Check if attachment can be restored
*
* @param int $attach_id
* @return bool
*/
function squeeze_can_restore($attach_id) {
$original_img_path = wp_get_original_image_path((int) $attach_id);
$backup_img_path = preg_replace("/(\.(?!.*\.))/", '.bak.', $original_img_path);
$can_restore = file_exists($backup_img_path);
return $can_restore;
}

View File

@ -0,0 +1,422 @@
<?php
// Exit if accessed directly.
if (!defined('ABSPATH')) {
exit;
}
add_action('admin_menu', 'squeeze_options_page');
/**
* Add submenu page with settings under Media
*/
function squeeze_options_page() {
add_submenu_page(
'upload.php',
__('Squeeze', 'squeeze'),
__('Squeeze', 'squeeze'),
'manage_options',
'squeeze',
'squeeze_options_page_html'
);
}
add_action('admin_menu', 'squeeze_options_bulk_page');
/**
* Add submenu page with bulk compression under Media
*/
function squeeze_options_bulk_page() {
add_submenu_page(
'upload.php',
__('Bulk Compress With Squeeze', 'squeeze'),
__('Squeeze Bulk', 'squeeze'),
'manage_options',
'squeeze-bulk',
'squeeze_options_bulk_page_html'
);
}
/**
* Bulk compression page callback function
*/
function squeeze_options_bulk_page_html() {
// check user capabilities
if (!current_user_can('manage_options')) {
return;
}
$mimes = array('image/jpeg', 'image/jpg', 'image/png');
$query_not_compressed = new WP_Query( array(
'post_type' => 'attachment',
'post_status' => 'inherit',
'post_mime_type' => $mimes,
'posts_per_page' => -1,
'fields' => 'ids',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'squeeze_is_compressed',
'compare' => 'NOT EXISTS'
),
array(
'key' => 'squeeze_is_compressed',
'compare' => '!=',
'value' => '1'
)
)
) );
$query_all = new WP_Query( array(
'post_type' => 'attachment',
'post_status' => 'inherit',
'post_mime_type' => $mimes,
'posts_per_page' => -1,
'fields' => 'ids',
) );
$uncompressed_count = $query_not_compressed->found_posts;
$total_count = $query_all->found_posts;
//$total_count = array_sum((array)wp_count_attachments("image"));
?>
<div class="wrap">
<h1>
<?php echo esc_html(get_admin_page_title()); ?>
</h1>
<p><?php _e('This page allows you to compress all images in your media library.', 'squeeze'); ?></p>
<p><strong><?php _e('Do not close this page during the compressing process.', 'squeeze'); ?></strong></p>
<p><?php _e('Please note that this process may take a long time depending on the number of images in your library.', 'squeeze'); ?></p>
<?php if ($uncompressed_count === 0) { ?>
<p><strong><?php _e('All images in your media library are compressed.', 'squeeze'); ?></strong></p>
<?php } else { ?>
<p><?php echo sprintf(__('You have <strong>%s</strong> uncompressed JPG/PNG images from total <strong>%s</strong> JPG/PNG images in your media library.', 'squeeze'), $uncompressed_count, $total_count); ?></p>
<input name="squeeze_bulk" class="button button-primary" type="button" value="<?php esc_attr_e( 'Optimise all images' ); ?>" />
<input type="hidden" value="<?php echo implode(",", $query_not_compressed->posts); ?>" name="squeeze_bulk_ids" />
<p><textarea name="squeeze_bulk_log" id="squeeze_bulk_log" cols="100" rows="10" readonly></textarea></p>
<?php } ?>
</div>
<?php
}
/**
* Options page callback function
*/
function squeeze_options_page_html() {
// check user capabilities
if (!current_user_can('manage_options')) {
return;
}
?>
<div class="wrap">
<h1>
<?php echo esc_html(get_admin_page_title()); ?>
</h1>
<form action="options.php" method="post">
<?php
settings_errors( 'squeeze_notices' );
settings_fields( 'squeeze_options' );
do_settings_sections( 'squeeze_options' ); ?>
<input name="submit" class="button button-primary" type="submit" value="<?php esc_attr_e( 'Save' ); ?>" />
<input name="restore" class="button button-secondary" type="button" value="<?php esc_attr_e( 'Restore defaults' ); ?>" />
</form>
</div>
<script>
(function() {
const restore = document.querySelector("input[name='restore']")
/**
* Handle restore defaults button click
*/
restore.addEventListener("click", (event) => {
jQuery.ajax({
url: squeeze.ajaxUrl,
type: 'POST',
data: {
action: 'squeeze_restore_defaults',
_ajax_nonce: squeeze.nonce
},
beforeSend: function () {
restore.disabled = true
},
error: function (error) {
console.error(error)
},
success: function (response) {
console.log(response)
if (response.success) {
window.location.replace(window.location.href + "&restore_defaults=true")
} else {
restore.disabled = false
window.location.replace(window.location.href + "&restore_defaults=false")
}
}
})
})
})()
</script>
<?php
}
add_action( 'admin_init', 'squeeze_register_settings' );
/**
* Register the settings and add the sections and fields
*/
function squeeze_register_settings() {
register_setting( 'squeeze_options', 'squeeze_options', 'squeeze_options_validate' );
add_settings_section( 'squeeze_basic_settings', __('Basic Settings', 'squeeze'), 'squeeze_setting_basic_desc', 'squeeze_options' );
add_settings_field( 'squeeze_setting_auto_compress', __('Auto compress', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_basic_settings', array( 'label_for' => 'auto_compress', 'class' => 'squeeze_setting_auto_compress', 'type' => 'checkbox' ) );
//add_settings_field( 'squeeze_setting_auto_compress_original', __('Auto compress original', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_basic_settings', array( 'label_for' => 'auto_compress_original', 'class' => 'squeeze_setting_auto_compress_original', 'type' => 'checkbox' ) );
add_settings_field( 'squeeze_setting_backup_original', __('Backup original image', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_basic_settings', array( 'label_for' => 'backup_original', 'class' => 'squeeze_setting_backup_original', 'type' => 'checkbox' ) );
add_settings_section( 'squeeze_jpeg_settings', __('JPEG Settings', 'squeeze'), 'squeeze_setting_jpeg_desc', 'squeeze_options' );
add_settings_field( 'squeeze_setting_jpeg_quality', __('Quality', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_quality', 'class' => 'squeeze_setting_jpeg_quality', 'type' => 'range' ) );
add_settings_field( 'squeeze_setting_jpeg_baseline', __('Pointless spec compliance', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_baseline', 'class' => 'squeeze_setting_jpeg_baseline', 'type' => 'checkbox' ) );
add_settings_field( 'squeeze_setting_jpeg_arithmetic', __('Arithmetic', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_arithmetic', 'class' => 'squeeze_setting_jpeg_arithmetic', 'type' => 'checkbox' ) );
add_settings_field( 'squeeze_setting_jpeg_progressive', __('Progressive rendering', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_progressive', 'class' => 'squeeze_setting_jpeg_progressive', 'type' => 'checkbox' ) );
add_settings_field( 'squeeze_setting_jpeg_optimize_coding', __('Optimize Huffman table', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_optimize_coding', 'class' => 'squeeze_setting_jpeg_optimize_coding', 'type' => 'checkbox' ) );
add_settings_field( 'squeeze_setting_jpeg_smoothing', __('Smoothing', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_smoothing', 'class' => 'squeeze_setting_jpeg_smoothing', 'type' => 'range' ) );
add_settings_field( 'squeeze_setting_jpeg_color_space', __('Channels', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_color_space', 'class' => 'squeeze_setting_jpeg_color_space', 'type' => 'select', 'options' => array( '3' => 'YCbCr', '1' => 'Grayscale', '2' => 'RGB' ) ) );
add_settings_field( 'squeeze_setting_jpeg_quant_table', __('Quantization', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_quant_table', 'class' => 'squeeze_setting_jpeg_quant_table', 'type' => 'select', 'options' => array(
'0' => 'JPEG Annex K',
'1' => 'Flat',
'2' => 'MSSIM-tuned Kodak',
'3' => 'ImageMagick',
'4' => 'PSNR-HVS-M-tuned Kodak',
'5' => 'Klein et al',
'6' => 'Watson et al' ,
'7' => 'Ahumada et al' ,
'8' => 'Peterson et al' ,
) ) );
add_settings_field( 'squeeze_setting_jpeg_trellis_multipass', __('Trellis multipass', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_trellis_multipass', 'class' => 'squeeze_setting_jpeg_trellis_multipass', 'type' => 'checkbox' ) );
add_settings_field( 'squeeze_setting_jpeg_trellis_opt_zero', __('Optimize zero block runs', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_trellis_opt_zero', 'class' => 'squeeze_setting_jpeg_trellis_opt_zero', 'type' => 'checkbox' ) );
add_settings_field( 'squeeze_setting_jpeg_trellis_opt_table', __('Optimize after trellis quantization', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_trellis_opt_table', 'class' => 'squeeze_setting_jpeg_trellis_opt_table', 'type' => 'checkbox' ) );
add_settings_field( 'squeeze_setting_jpeg_trellis_loops', __('Trellis quantization passes', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_trellis_loops', 'class' => 'squeeze_setting_jpeg_trellis_loops', 'type' => 'range', 'min' => 1, 'max' => 50 ) );
add_settings_field( 'squeeze_setting_jpeg_auto_subsample', __('Auto subsample chroma', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_auto_subsample', 'class' => 'squeeze_setting_jpeg_auto_subsample', 'type' => 'checkbox' ) );
add_settings_field( 'squeeze_setting_jpeg_chroma_subsample', __('Subsample chroma by', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_chroma_subsample', 'class' => 'squeeze_setting_jpeg_chroma_subsample', 'type' => 'range', 'min' => 1, 'max' => 4 ) );
add_settings_field( 'squeeze_setting_jpeg_separate_chroma_quality', __('Separate chroma quality', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_separate_chroma_quality', 'class' => 'squeeze_setting_jpeg_separate_chroma_quality', 'type' => 'checkbox' ) );
add_settings_field( 'squeeze_setting_jpeg_chroma_quality', __('Chroma quality', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_chroma_quality', 'class' => 'squeeze_setting_jpeg_chroma_quality', 'type' => 'range', ) );
add_settings_section( 'squeeze_png_settings', __('PNG Settings', 'squeeze'), 'squeeze_setting_png_desc', 'squeeze_options' );
add_settings_field( 'squeeze_setting_png_level', __('Effort', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_png_settings', array( 'label_for' => 'png_level', 'class' => 'squeeze_setting_png_level', 'type' => 'range', 'min' => 0, 'max' => 3 ) );
add_settings_field( 'squeeze_setting_png_interlace', __('Interlace', 'squeeze'), 'squeeze_options_callback', 'squeeze_options', 'squeeze_png_settings', array( 'label_for' => 'png_interlace', 'class' => 'squeeze_setting_png_interlace', 'type' => 'checkbox' ) );
}
/**
* Sanitize and validate input. Accepts an array, return a sanitized array.
* @param array $input
*/
function squeeze_options_validate( $input ) {
$input['jpeg_quality'] = absint($input['jpeg_quality']);
$input['jpeg_smoothing'] = absint($input['jpeg_smoothing']);
$input['jpeg_color_space'] = absint($input['jpeg_color_space']);
$input['jpeg_quant_table'] = absint($input['jpeg_quant_table']);
$input['jpeg_trellis_loops'] = absint($input['jpeg_trellis_loops']);
$input['jpeg_chroma_subsample'] = absint($input['jpeg_chroma_subsample']);
$input['jpeg_chroma_quality'] = absint($input['jpeg_chroma_quality']);
$input['png_level'] = absint($input['png_level']);
$input['jpeg_baseline'] = isset( $input['jpeg_baseline'] ) ? $input['jpeg_baseline'] : '0';
$input['jpeg_arithmetic'] = isset( $input['jpeg_arithmetic'] ) ? $input['jpeg_arithmetic'] : '0';
$input['jpeg_progressive'] = isset( $input['jpeg_progressive'] ) ? $input['jpeg_progressive'] : '0';
$input['jpeg_optimize_coding'] = isset( $input['jpeg_optimize_coding'] ) ? $input['jpeg_optimize_coding'] : '0';
$input['jpeg_trellis_multipass'] = isset( $input['jpeg_trellis_multipass'] ) ? $input['jpeg_trellis_multipass'] : '0';
$input['jpeg_trellis_opt_zero'] = isset( $input['jpeg_trellis_opt_zero'] ) ? $input['jpeg_trellis_opt_zero'] : '0';
$input['jpeg_trellis_opt_table'] = isset( $input['jpeg_trellis_opt_table'] ) ? $input['jpeg_trellis_opt_table'] : '0';
$input['jpeg_auto_subsample'] = isset( $input['jpeg_auto_subsample'] ) ? $input['jpeg_auto_subsample'] : '0';
$input['jpeg_separate_chroma_quality'] = isset( $input['jpeg_separate_chroma_quality'] ) ? $input['jpeg_separate_chroma_quality'] : '0';
$input['png_interlace'] = isset( $input['png_interlace'] ) ? $input['png_interlace'] : '0';
$input['auto_compress'] = isset( $input['auto_compress'] ) ? $input['auto_compress'] : '0';
//$input['auto_compress_original'] = isset( $input['auto_compress_original'] ) ? $input['auto_compress_original'] : '0';
$input['backup_original'] = isset( $input['backup_original'] ) ? $input['backup_original'] : '0';
add_settings_error( 'squeeze_notices', 'settings_updated', __( 'Settings have been updated.', 'squeeze' ), 'success' );
return $input;
}
/**
* Display and fill the form field
* @param array $args
*/
function squeeze_options_callback( $args ) {
$label_for = $args['label_for'];
$class = $args['class'];
$type = $args['type'];
$default = squeeze_get_default_value($label_for);
$options = get_option( 'squeeze_options' );
switch ($type) {
case 'text':
$value = isset($options[$label_for]) ? $options[$label_for] : $default;
echo "<input id='squeeze_setting_".esc_attr($label_for)."' name='squeeze_options[".esc_attr($label_for)."]' type='text' value='" . esc_attr( $value ) . "' />";
break;
case 'range':
$value = isset($options[$label_for]) ? $options[$label_for] : $default;
$min = isset($args['min']) ? $args['min'] : 0;
$max = isset($args['max']) ? $args['max'] : 100;
$step = isset($args['step']) ? $args['step'] : 1;
echo "<input id='squeeze_setting_".esc_attr($label_for)."' name='squeeze_options[".esc_attr($label_for)."]' min='".(int)$min."' max='".(int)$max."' step='".(int)$step."' type='range' value='" . esc_attr( $value ) . "' />";
echo '<output id="squeeze_setting_'.esc_attr($label_for).'_value"></output>';
?>
<script>
(function () {
const value = document.querySelector("#squeeze_setting_<?php echo esc_attr($label_for); ?>_value")
const input = document.querySelector("#squeeze_setting_<?php echo esc_attr($label_for); ?>")
value.textContent = input.value
input.addEventListener("input", (event) => {
value.textContent = event.target.value
})
})()
</script>
<?php
break;
case 'checkbox':
$value = isset($options[$label_for]) ? (bool) $options[$label_for] : $default;
echo "<input id='squeeze_setting_".esc_attr($label_for)."' name='squeeze_options[".esc_attr($label_for)."]' type='checkbox' ".checked( $value, true, false )." />";
break;
case 'select':
$value = isset($options[$label_for]) ? $options[$label_for] : $default;
echo "<select id='squeeze_setting_".esc_attr($label_for)."' name='squeeze_options[".esc_attr($label_for)."]'>";
foreach ($args['options'] as $key => $option) {
echo "<option value='".esc_attr($key)."' ".selected( $value, $key, false ).">".esc_html($option)."</option>";
}
echo "</select>";
break;
}
}
/**
* Get default value for option
* @param string $option
* @param bool $all
*/
function squeeze_get_default_value ( $option, $all = false ) {
$options_defaults = apply_filters('squeeze_options_default',
array(
// JPEG settings
'jpeg_quality' => 75,
'jpeg_baseline' => false,
'jpeg_arithmetic' => false,
'jpeg_progressive' => true,
'jpeg_optimize_coding' => true,
'jpeg_smoothing' => 0,
'jpeg_color_space' => 3,
'jpeg_quant_table' => 3,
'jpeg_trellis_multipass' => false,
'jpeg_trellis_opt_zero' => false,
'jpeg_trellis_opt_table' => false,
'jpeg_trellis_loops' => 1,
'jpeg_auto_subsample' => true,
'jpeg_chroma_subsample' => 2,
'jpeg_separate_chroma_quality' => false,
'jpeg_chroma_quality' => 75,
// PNG settings
'png_level' => 2,
'png_interlace' => false,
// General settings
'auto_compress' => true,
//'auto_compress_original' => false,
'backup_original' => true,
)
);
if ($all) {
return $options_defaults;
}
return in_array($option, array_keys($options_defaults)) ? $options_defaults[$option] : false;
}
function squeeze_setting_basic_desc() {
echo '<p>'.__('Basic options', 'squeeze').'</p>';
}
function squeeze_setting_jpeg_desc() {
echo '<p>'.__('Compress settings for JPEG images using MozJPEG encoder', 'squeeze').'</p>';
}
function squeeze_setting_png_desc() {
echo '<p>'.__('Compress settings for PNG images using OxiPNG encoder', 'squeeze').'</p>';
}
add_action('wp_ajax_squeeze_restore_defaults', 'squeeze_restore_defaults');
/**
* Restore default settings
*/
function squeeze_restore_defaults() {
check_ajax_referer( 'squeeze-nonce', '_ajax_nonce' );
if (get_option('squeeze_options')) {
$result = delete_option('squeeze_options', "");
if (!$result) {
wp_send_json_error($result);
}
wp_send_json_success($result);
}
wp_send_json_success(true);
}
add_action( 'admin_init', 'squeeze_add_notices' );
/**
* Add custom admin notices
*/
function squeeze_add_notices() {
global $pagenow;
if ( is_admin() && $pagenow === "upload.php" && isset($_GET['page']) && $_GET['page'] === "squeeze" && isset($_GET['restore_defaults']) && !isset($_GET['settings-updated']) ) {
add_settings_error( 'squeeze_notices', 'settings_restored', __( 'Settings have been restored.', 'squeeze' ), 'success' );
}
}
add_filter('attachment_fields_to_edit', 'squeeze_add_custom_field_to_attachment', 10, 2);
/**
* Add custom text/textarea attachment field
*/
function squeeze_add_custom_field_to_attachment( $form_fields, $post ) {
$allowed_mimes = array(
'image/jpeg',
'image/png',
);
if ( in_array( $post->post_mime_type, $allowed_mimes ) ) {
$is_compressed = get_post_meta($post->ID, 'squeeze_is_compressed', true);
$can_restore = squeeze_can_restore($post->ID);
$form_fields['squeeze_is_compressed'] = array(
'label' => __('Squeeze', 'squeeze'),
'input' => 'html',
'html' => $is_compressed ?
'<label><span class="squeeze_status"><span style="padding-top: 0; line-height: 1; color: green;" class="dashicons dashicons-yes-alt"></span>&nbsp;' . __('Compressed', 'squeeze') . '</span></label>' . ($can_restore ? '
<br><br><button name="squeeze_restore" type="button" class="button button-secondary squeeze-restore-button" data-attachment="' . $post->ID . '">' . __('Restore original', 'squeeze') . '</button>' : '')
:
'<label><span class="squeeze_status"><span style="padding-top: 0; line-height: 1; color: red;" class="dashicons dashicons-no-alt"></span>&nbsp;' . __('Not compressed', 'squeeze') . '</span></label>
<br><br><button name="squeeze_compress_single" type="button" class="button button-primary squeeze-compress-button" data-attachment="' . $post->ID . '">' . __('Compress', 'squeeze') . '</button>'
);
}
return $form_fields;
}
add_filter( 'manage_media_columns', 'squeeze_add_media_columns' );
/**
* Filter the Media list table columns to add a Squeeze column.
*
* @param array $posts_columns Existing array of columns displayed in the Media list table.
* @return array Amended array of columns to be displayed in the Media list table.
*/
function squeeze_add_media_columns( $posts_columns ) {
$posts_columns['squeeze'] = __( 'Squeeze', 'squeeze' );
return $posts_columns;
}
add_action( 'manage_media_custom_column', 'squeeze_media_custom_column', 10, 2 );
/**
* Display attachment uploaded time under `Time` custom column in the Media list table.
*
* @param string $column_name Name of the custom column.
*/
function squeeze_media_custom_column( $column_name, $post_id ) {
if ( 'squeeze' !== $column_name ) {
return;
}
$form_fields = squeeze_add_custom_field_to_attachment( array(), get_post( $post_id ) );
if ($form_fields)
echo wp_kses_post($form_fields['squeeze_is_compressed']['html']);
}