From 090954ba188817b0ed7182f1fb9b44fff06ee444 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 5 Feb 2026 14:44:36 +0800 Subject: [PATCH 01/11] feat: metabox, gravity forms --- src/admin/class-script-loader.php | 2 ++ src/admin/js/media-manager/select-files.js | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/admin/class-script-loader.php b/src/admin/class-script-loader.php index c719573..897592d 100644 --- a/src/admin/class-script-loader.php +++ b/src/admin/class-script-loader.php @@ -27,6 +27,8 @@ public function __construct() { add_action( 'et_fb_enqueue_assets', [ $this, 'enqueue_cimo_assets' ] ); // Enqueue for the admin area in general. add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_cimo_assets' ] ); + // Enqueue in frontend for forms plugin + add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_cimo_assets' ] ); } /** diff --git a/src/admin/js/media-manager/select-files.js b/src/admin/js/media-manager/select-files.js index 5323291..7e7195b 100644 --- a/src/admin/js/media-manager/select-files.js +++ b/src/admin/js/media-manager/select-files.js @@ -49,7 +49,9 @@ function addSelectFilesListenerToFileUploads( targetDocument ) { if ( ! event.target.closest( '.components-form-file-upload' ) && // Allow uploads to the image block ! event.target.closest( '.media-frame' ) && // Allow uploads from the Media Manager ! event.target.closest( '.media-upload-form' ) && // Allow uploads from the admin Media > Add Media File - ! event.target.closest( '.moxie-shim' ) ) { // Allow uploads from the admin Media > Library grid view + ! event.target.closest( '.moxie-shim' ) && // Allow uploads from the admin Media > Library grid view + ! event.target.closest( '.rwmb-meta-box' ) && // Allow uploads from Metabox Custom Fields + ! event.target.closest( '.gfield--type-fileupload ' ) ) { // Allow uploads from Gravity Forms > File Upload return } From 55abbcf1d31ef1952976f5e286b1f55f90148a43 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Fri, 6 Feb 2026 23:33:46 +0800 Subject: [PATCH 02/11] fix: remove extra space --- src/admin/js/media-manager/select-files.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/admin/js/media-manager/select-files.js b/src/admin/js/media-manager/select-files.js index 7e7195b..793797a 100644 --- a/src/admin/js/media-manager/select-files.js +++ b/src/admin/js/media-manager/select-files.js @@ -51,7 +51,7 @@ function addSelectFilesListenerToFileUploads( targetDocument ) { ! event.target.closest( '.media-upload-form' ) && // Allow uploads from the admin Media > Add Media File ! event.target.closest( '.moxie-shim' ) && // Allow uploads from the admin Media > Library grid view ! event.target.closest( '.rwmb-meta-box' ) && // Allow uploads from Metabox Custom Fields - ! event.target.closest( '.gfield--type-fileupload ' ) ) { // Allow uploads from Gravity Forms > File Upload + ! event.target.closest( '.gfield--type-fileupload' ) ) { // Allow uploads from Gravity Forms > File Upload return } From 16e6c8386b9e6228c92cd0976f2621793e598986 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 9 Feb 2026 11:24:03 +0800 Subject: [PATCH 03/11] feat: move location list to premium --- src/admin/js/media-manager/select-files.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/admin/js/media-manager/select-files.js b/src/admin/js/media-manager/select-files.js index 793797a..9879add 100644 --- a/src/admin/js/media-manager/select-files.js +++ b/src/admin/js/media-manager/select-files.js @@ -10,6 +10,15 @@ import { getFileConverter, requiresFileConversion } from '~cimo/shared/converter import { watchForEditorIframe } from '~cimo/shared/util' import { saveMetadata } from '~cimo/shared/metadata-saver' import { ProgressModal } from './progress-modal' +import { applyFilters } from '@wordpress/hooks' + +// Allowed locations to be able to select files. +const ALLOWED_LOCATIONS = applyFilters( 'cimo.selectFiles.allowedLocations', [ + '.components-form-file-upload', // Allow uploads to the image block + '.media-frame', // Allow uploads from the Media Manager + '.media-upload-form', // Allow uploads from the admin Media > Add Media File + '.moxie-shim', // Allow uploads from the admin Media > Library grid view +] ) // Add event listener to the Media Manager's drop zone function addSelectFilesListenerToFileUploads( targetDocument ) { @@ -46,12 +55,8 @@ function addSelectFilesListenerToFileUploads( targetDocument ) { // selects that we want to, like the media manager picker or the image // block uploader. // Allow these locations to be able to select files. - if ( ! event.target.closest( '.components-form-file-upload' ) && // Allow uploads to the image block - ! event.target.closest( '.media-frame' ) && // Allow uploads from the Media Manager - ! event.target.closest( '.media-upload-form' ) && // Allow uploads from the admin Media > Add Media File - ! event.target.closest( '.moxie-shim' ) && // Allow uploads from the admin Media > Library grid view - ! event.target.closest( '.rwmb-meta-box' ) && // Allow uploads from Metabox Custom Fields - ! event.target.closest( '.gfield--type-fileupload' ) ) { // Allow uploads from Gravity Forms > File Upload + const isAllowed = ALLOWED_LOCATIONS.some( selector => event.target.closest( selector ) ) + if ( ! isAllowed ) { return } From 7ed44edada23fc93447fd3ee6ebbe11ec67b6b07 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Wed, 11 Feb 2026 15:06:02 +0800 Subject: [PATCH 04/11] fix: add forms integration for dropZone, including for DropzoneJs --- src/admin/js/media-manager/drop-zone.js | 37 +++++++++++++++++++------ 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/admin/js/media-manager/drop-zone.js b/src/admin/js/media-manager/drop-zone.js index 674edad..e79e25e 100644 --- a/src/admin/js/media-manager/drop-zone.js +++ b/src/admin/js/media-manager/drop-zone.js @@ -10,12 +10,22 @@ import { getFileConverter, requiresFileConversion } from '~cimo/shared/converter import { watchForEditorIframe } from '~cimo/shared/util' import { saveMetadata } from '~cimo/shared/metadata-saver' import { ProgressModal } from './progress-modal' +import { applyFilters } from '@wordpress/hooks' /** * Intercept editor media uploads and convert images to WebP on the client * before uploading to WordPress. This affects the block editor only. */ +// Allowed locations to be able to select files. +const ALLOWED_LOCATIONS = applyFilters( 'cimo.dropZone.allowedLocations', [ + '.media-frame-uploader', // Allowed to drop in the Media Manager + '.media-upload-form', // Allowed to drop in the admin Media > Add Media File + '.editor-post-featured-image', // Allowed to drop in the featured image drop zone + '.editor-styles-wrapper', // Allowed to drop in the block editor when adding new image blocks + '.uploader-window', // Allowed to drop in the admin Media > Library grid view +] ) + // Add event listener to the Media Manager's drop zone function addDropZoneListenerToMediaManager( targetDocument ) { if ( ! targetDocument ) { @@ -45,12 +55,21 @@ function addDropZoneListenerToMediaManager( targetDocument ) { // TODO: We also want to filter out the target so we can set when this // is triggered. We might break other funcitonality that we don't have // the conversion to happen. - if ( ! event.target.closest( '.media-frame-uploader' ) && // Allowed to drop in the Media Manager - ! event.target.closest( '.supports-drag-drop' ).querySelector( '.media-frame-uploader' ) && // Allowed a fallback to drop in the Media Manager - ! event.target.closest( '.media-upload-form' ) && // Allowed to drop in the admin Media > Add Media File. - ! event.target.closest( '.editor-post-featured-image' ) && // Allowed to drop in the featured image drop zone. - ! event.target.closest( '.editor-styles-wrapper' ) && // Allowed to drop in the block editor when adding new image blocks - ! event.target.closest( '.uploader-window' ) ) { // Allowed to drop in the admin Media > Library grid view + + // Find the matched element based on the locations + let matchedElement + for ( const location of ALLOWED_LOCATIONS ) { + matchedElement = event.target.closest( location ) + if ( matchedElement ) { + break + } + } + + // Allowed a fallback to drop in the Media Manager + matchedElement = matchedElement || event.target.closest( '.supports-drag-drop' ) + ?.querySelector( '.media-frame-uploader' ) + + if ( ! matchedElement ) { return } @@ -140,9 +159,11 @@ function addDropZoneListenerToMediaManager( targetDocument ) { // Target the current dropzone event.target.dispatchEvent( dropEvent ) } else { - // Find the file input inside the Media Manager modal // TODO: There might be a better way to do this. - const fileInput = document.querySelector( '.media-modal input[type="file"]' ) || + // Find the file input based on the matched element + const fileInput = matchedElement.querySelector( 'input[type="file"]' ) || + // Find inside the Media Manager modal + document.querySelector( '.media-modal input[type="file"]' ) || // Fallback, this is the Media > Add Media File document.querySelector( '.media-upload-form input[type="file"]' ) || // Just in case From f096c957f1185fd68d7bc2da2e13190bb8be09af Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 19 Feb 2026 11:04:05 +0800 Subject: [PATCH 05/11] fix: add upsell --- src/admin/js/page/admin-settings.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/admin/js/page/admin-settings.js b/src/admin/js/page/admin-settings.js index a71ea8a..0a781f6 100644 --- a/src/admin/js/page/admin-settings.js +++ b/src/admin/js/page/admin-settings.js @@ -935,6 +935,15 @@ const AdminSettings = () => { { __( 'Optimize SVG files on upload', 'cimo-image-optimizer' ) } +
  • + + { /* Frontend Forms Icon */ } + + + + { __( 'Frontend Forms Support', 'cimo-image-optimizer' ) } + +

  • From 142808ee4f016112e93416fdde702a5af27d5b3a Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Thu, 19 Feb 2026 12:02:09 +0800 Subject: [PATCH 06/11] fix: enqueue cimo assets in frontend only if forms exist --- src/admin/class-script-loader.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/admin/class-script-loader.php b/src/admin/class-script-loader.php index c2bf27f..2bc9e42 100644 --- a/src/admin/class-script-loader.php +++ b/src/admin/class-script-loader.php @@ -27,8 +27,21 @@ public function __construct() { add_action( 'et_fb_enqueue_assets', [ $this, 'enqueue_cimo_assets' ] ); // Enqueue for the admin area in general. add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_cimo_assets' ] ); + // Enqueue in frontend for forms plugin - add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_cimo_assets' ] ); + // These hooks only run if the respective forms exist in the frontend. + if( CIMO_BUILD === 'premium' ) { + // Fluent Forms + add_action( 'fluentform/load_form_assets', [ $this, 'enqueue_cimo_assets' ] ); + // Gravity Forms + add_action( 'gform_enqueue_scripts', [ $this, 'enqueue_cimo_assets' ] ); + // WS Forms + add_action( 'wsf_enqueue_scripts', [ $this, 'enqueue_cimo_assets' ] ); + // Ninja Forms + add_action( 'ninja_forms_enqueue_scripts', [ $this, 'enqueue_cimo_assets' ]); + // Contact Form 7 + add_action( 'wpcf7_contact_form', [ $this, 'enqueue_cimo_assets' ] ); + } } /** From 44061921daef9f2d5b4b0519867f9876534ddc51 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 24 Feb 2026 15:34:14 +0800 Subject: [PATCH 07/11] fix: allow any input files in premium frontend --- src/admin/class-script-loader.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/admin/class-script-loader.php b/src/admin/class-script-loader.php index 2bc9e42..b850856 100644 --- a/src/admin/class-script-loader.php +++ b/src/admin/class-script-loader.php @@ -99,6 +99,7 @@ public function enqueue_cimo_assets() { [ 'restUrl' => rest_url( 'cimo/v1/' ), 'nonce' => wp_create_nonce( 'wp_rest' ), + 'isFrontend' => ! is_admin(), 'webpQuality' => ! empty( $settings['webp_quality'] ) ? (int) $settings['webp_quality'] : 80, 'maxImageDimension' => ! empty( $settings['max_image_dimension'] ) ? (int) $settings['max_image_dimension'] : 0, 'videoOptimizationEnabled' => isset( $settings['video_optimization_enabled'] ) ? (int) $settings['video_optimization_enabled'] : 1, From 2ae93a4cc03c2c485920caa50815833980b3e503 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 24 Feb 2026 16:12:19 +0800 Subject: [PATCH 08/11] fix: continue optimizing if metadata saving fails for unathorized users --- src/shared/metadata-saver.js | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/shared/metadata-saver.js b/src/shared/metadata-saver.js index 10de99c..4f149ad 100644 --- a/src/shared/metadata-saver.js +++ b/src/shared/metadata-saver.js @@ -11,6 +11,12 @@ * @param {Array} _metadataArray - Array of metadata objects (each must have a filename key) */ export const saveMetadata = _metadataArray => { + const isFrontend = window.cimoSettings && window.cimoSettings.isFrontend + + if ( isFrontend ) { + return Promise.resolve() + } + if ( ! Array.isArray( _metadataArray ) ) { return Promise.resolve() } @@ -50,7 +56,11 @@ export const saveMetadata = _metadataArray => { .then( response => { if ( ! response.ok ) { return response.json().then( err => { - throw new Error( err.message || response.statusText ) + const newError = new Error( err.message || response.statusText ) + newError.status = response.status + newError.code = err.code + + throw newError } ) } return response.json() @@ -65,6 +75,20 @@ export const saveMetadata = _metadataArray => { resolve( data ) } ) .catch( error => { + const isUnauthorized = error.status === 401 || + error.status === 403 || + error.code === 'rest_cannot_create' || + error.code === 'rest_forbidden' + + if ( isUnauthorized ) { + // eslint-disable-next-line no-console + console.warn( + `Skipping metadata save — user not authorized.` + ) + resolve() + return + } + // eslint-disable-next-line no-console console.error( `Failed to save metadata for filenames: [${ metadataArray.map( m => m.filename ).join( ', ' ) }]:`, From 6831c30ddfed3567665dc569c9d59247cf5f7f74 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Tue, 24 Feb 2026 22:22:51 +0800 Subject: [PATCH 09/11] fix: remove guard for opting out metadata saving in frontend for now --- src/shared/metadata-saver.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/shared/metadata-saver.js b/src/shared/metadata-saver.js index 4f149ad..7656b6d 100644 --- a/src/shared/metadata-saver.js +++ b/src/shared/metadata-saver.js @@ -11,12 +11,6 @@ * @param {Array} _metadataArray - Array of metadata objects (each must have a filename key) */ export const saveMetadata = _metadataArray => { - const isFrontend = window.cimoSettings && window.cimoSettings.isFrontend - - if ( isFrontend ) { - return Promise.resolve() - } - if ( ! Array.isArray( _metadataArray ) ) { return Promise.resolve() } From 5c474adcf9f9e59c87503274b95fa2a83b93094e Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Wed, 25 Feb 2026 23:21:45 +0800 Subject: [PATCH 10/11] fix: skip metadata saving in frontend for unauthenticated users; remove warning --- src/shared/metadata-saver.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/shared/metadata-saver.js b/src/shared/metadata-saver.js index 7656b6d..7fab631 100644 --- a/src/shared/metadata-saver.js +++ b/src/shared/metadata-saver.js @@ -11,6 +11,13 @@ * @param {Array} _metadataArray - Array of metadata objects (each must have a filename key) */ export const saveMetadata = _metadataArray => { + const { isFrontend = false, isLoggedIn = false } = window.cimoSettings ?? {} + + // If we're on the frontend and the user is not logged in, we can't save metadata, so we just return. + if ( isFrontend && ! isLoggedIn ) { + return Promise.resolve() + } + if ( ! Array.isArray( _metadataArray ) ) { return Promise.resolve() } @@ -74,11 +81,9 @@ export const saveMetadata = _metadataArray => { error.code === 'rest_cannot_create' || error.code === 'rest_forbidden' + // If the error is due to unauthorized access, we resolve the promise without rejecting, + // since this is not a failure and we don't want to spam users. if ( isUnauthorized ) { - // eslint-disable-next-line no-console - console.warn( - `Skipping metadata save — user not authorized.` - ) resolve() return } From 532791da87b61bfd23a6f05fdba3338c777a5dd2 Mon Sep 17 00:00:00 2001 From: Alquen Sarmiento Date: Mon, 2 Mar 2026 23:27:08 +0800 Subject: [PATCH 11/11] fix: add jetformbuilder --- src/admin/class-script-loader.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/admin/class-script-loader.php b/src/admin/class-script-loader.php index b850856..7f7d8bc 100644 --- a/src/admin/class-script-loader.php +++ b/src/admin/class-script-loader.php @@ -41,6 +41,8 @@ public function __construct() { add_action( 'ninja_forms_enqueue_scripts', [ $this, 'enqueue_cimo_assets' ]); // Contact Form 7 add_action( 'wpcf7_contact_form', [ $this, 'enqueue_cimo_assets' ] ); + // JetFormBuilder + add_action( 'jet-form-builder/before-start-form-row', [ $this, 'enqueue_cimo_assets' ] ); } } @@ -100,6 +102,7 @@ public function enqueue_cimo_assets() { 'restUrl' => rest_url( 'cimo/v1/' ), 'nonce' => wp_create_nonce( 'wp_rest' ), 'isFrontend' => ! is_admin(), + 'isLoggedIn' => is_user_logged_in(), 'webpQuality' => ! empty( $settings['webp_quality'] ) ? (int) $settings['webp_quality'] : 80, 'maxImageDimension' => ! empty( $settings['max_image_dimension'] ) ? (int) $settings['max_image_dimension'] : 0, 'videoOptimizationEnabled' => isset( $settings['video_optimization_enabled'] ) ? (int) $settings['video_optimization_enabled'] : 1,