: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
import Smush from '../smush/smush';
import {GlobalStats} from "../common/globalStats";
import SmushProgress from "../common/progressbar";
const remove_element = function (el, timeout) {
if (typeof timeout === 'undefined') {
el.fadeTo(timeout, 0, function () {
el.slideUp(timeout, function () {
* Disable the action links *
const disable_links = function (c_element) {
const parent = c_element.parent();
parent.css({ opacity: '0.5' });
parent.find('a').prop('disabled', true);
* Enable the Action Links *
const enable_links = function (c_element) {
const parent = c_element.parent();
parent.css({ opacity: '1' });
parent.find('a').prop('disabled', false);
* Restore image request with a specified action for Media Library / NextGen Gallery
* @param {string} currentButton
* @param {string} smushAction
const process_smush_action = function (
if ( currentButton.attr( 'disabled' ) ) {
$('.wp-smush-error').remove();
$('.smush-stats-wrapper').hide();
if ('smush_restore_image' === smushAction) {
if ($(document).find('div.media-modal.wp-core-ui').length > 0) {
window.location.search.indexOf('item') > -1
// Get the image ID and nonce.
attachment_id: currentButton.data('id'),
_nonce: currentButton.data('nonce'),
// Reduce the opacity of stats and disable the click.
disable_links(currentButton);
const oldLabel = currentButton.html();
'<span class="spinner wp-smush-progress">' +
$.post(ajaxurl, params, function (r) {
// Reset all functionality.
enable_links(currentButton);
if (r.success && 'undefined' !== typeof r.data) {
// Replace in immediate parent for NextGEN.
'undefined' !== typeof this.data &&
this.data.indexOf('nextgen') > -1
// Show the smush button, and remove stats and restore option.
currentButton.parents().eq(1).html(r.data.stats);
} else if ('restore' === action) {
// Show the smush button, and remove stats and restore option.
currentButton.parents().eq(1).html(r.data.stats);
const wrapper = currentButton.parents().eq(1);
if ( wp_smush_msgs.failed_item_smushed && wrapper.hasClass('smush-failed-processing') ) {
wrapper.html( '<p class="smush-status smush-success">' + wp_smush_msgs.failed_item_smushed + '</p>' );
if ('undefined' !== typeof r.data && 'restore' === action) {
Smush.updateImageStats(r.data.new_size);
} else if (r.data && r.data.error_msg) {
-1 === this.data.indexOf('nextgen')
currentButton.closest( '.smushit' ).find('.smush-status').addClass('smush-warning').html(r.data.error_msg);
currentButton.parent().append(r.data.error_msg);
// Reset label and disable button on error.
currentButton.attr('disabled', true);
currentButton.html( oldLabel );
* Validates the Resize Width and Height against the Largest Thumbnail Width and Height
* @param wrapper_div jQuery object for the whole setting row wrapper div
* @param width_only Whether to validate only width
* @param height_only Validate only Height
* @return {boolean} All Good or not
const validate_resize_settings = function (
const resize_checkbox = wrapper_div.find('#resize');
var width_input = wrapper_div.find('#wp-smush-resize_width');
var width_error_note = wrapper_div.find(
'.sui-notice-info.wp-smush-update-width'
var height_input = wrapper_div.find('#wp-smush-resize_height');
var height_error_note = wrapper_div.find(
'.sui-notice-info.wp-smush-update-height'
let height_error = false;
//If resize settings is not enabled, return true
if (!resize_checkbox.is(':checked')) {
//Check if we have localised width and height
'undefined' === typeof wp_smushit_data.resize_sizes ||
'undefined' === typeof wp_smushit_data.resize_sizes.width
//Rely on server validation
'undefined' !== typeof width_input &&
parseInt(wp_smushit_data.resize_sizes.width) >
parseInt(width_input.val())
width_input.parent().addClass('sui-form-field-error');
width_error_note.show('slow');
width_input.parent().removeClass('sui-form-field-error');
if (height_input.hasClass('error')) {
height_error_note.show('slow');
'undefined' !== typeof height_input &&
parseInt(wp_smushit_data.resize_sizes.height) >
parseInt(height_input.val())
height_input.parent().addClass('sui-form-field-error');
//If we are not showing the width error already
height_error_note.show('slow');
height_input.parent().removeClass('sui-form-field-error');
height_error_note.hide();
if (width_input.hasClass('error')) {
width_error_note.show('slow');
if (width_error || height_error) {
* Update the progress bar width if we have images that needs to be resmushed
const update_progress_bar_resmush = function (unsmushed_count) {
if ('undefined' === typeof unsmushed_count) {
const smushed_count = wp_smushit_data.count_total - unsmushed_count;
//Update the Progress Bar Width
const $progress_bar = jQuery(
'.bulk-smush-wrapper .wp-smush-progress-inner'
if ($progress_bar.length < 1) {
const width = (smushed_count / wp_smushit_data.count_total) * 100;
$progress_bar.css('width', width + '%');
const runRecheck = function (process_settings) {
const button = $('.wp-smush-scan');
// Add a "loading" state to the button.
button.addClass('sui-button-onload');
// Check if type is set in data attributes.
let scan_type = button.data('type');
scan_type = 'undefined' === typeof scan_type ? 'media' : scan_type;
// Remove the Skip resmush attribute from button.
$('.wp-smush-all').removeAttr('data-smush');
// Disable Bulk smush button and itself.
$('.wp-smush-all').prop('disabled', true);
// Hide Settings changed Notice.
$('.wp-smush-settings-changed').hide();
action: 'scan_for_resmush',
wp_smush_options_nonce: jQuery('#wp_smush_options_nonce').val(),
// Send ajax request and get ids if any.
$.get(ajaxurl, params, function (response) {
if ( ! response?.success ) {
WP_Smush.helpers.showNotice( response, {
const stats = response.data;
showRecheckImagesNotice( stats );
GlobalStats.updateGlobalStatsFromSmushScriptData( stats );
GlobalStats.renderStats();
updateBulkSmushContentAfterReCheck( stats );
// Hide the progress bar.
'.bulk-smush-wrapper .wp-smush-bulk-progress-bar-wrapper'
).addClass('sui-hidden');
// Add check complete status to button.
.removeClass('sui-button-onload')
.addClass('smush-button-check-success');
const $defaultText = button.find('.wp-smush-default-text'),
$completedText = button.find('.wp-smush-completed-text');
$defaultText.addClass('sui-hidden-important');
$completedText.removeClass('sui-hidden');
// Remove success message from button.
button.removeClass('smush-button-check-success');
$defaultText.removeClass('sui-hidden-important');
$completedText.addClass('sui-hidden');
$('.wp-smush-all').prop('disabled', false);
const showRecheckImagesNotice = ( stats ) => {
if ( 'undefined' !== typeof stats.noticeType ) {
'<p>' + stats.notice + '</p>',
{ type, icon: 'check-tick' }
const updateBulkSmushContentAfterReCheck = ( stats ) => {
if ( SmushProgress.isEmptyObject ) {
SmushProgress.update( 0, stats.remaining_count );
if ( stats.remaining_count < 1 ) {
SmushProgress.hideBulkSmushDescription();
SmushProgress.showBulkSmushAllDone();
SmushProgress.showBulkSmushDescription();
SmushProgress.hideBulkSmushAllDone();
const updateDisplayedContentAfterReCheck = function (count) {
const $pendingImagesWrappers = jQuery(
'.bulk-smush-wrapper .wp-smush-bulk-wrapper'
const $allDoneWrappers = jQuery(
'.bulk-smush-wrapper .wp-smush-all-done'
if ($pendingImagesWrappers.length && $allDoneWrappers.length) {
$pendingImagesWrappers.addClass('sui-hidden');
$allDoneWrappers.find('p').html( wp_smush_msgs.all_smushed );
$allDoneWrappers.find('.sui-notice-icon').removeClass('sui-icon-info').addClass('sui-icon-check-tick');
$allDoneWrappers.removeClass('sui-notice-warning').addClass('sui-notice-success');
$allDoneWrappers.removeClass('sui-hidden');
$pendingImagesWrappers.removeClass('sui-hidden');
$allDoneWrappers.addClass('sui-hidden');
// Update texts mentioning the amount of unsmushed imagesin the summary icon tooltip.
const $unsmushedTooltip = jQuery(
'.sui-summary-smush .sui-summary-details .sui-tooltip'
// The tooltip doesn't exist in the NextGen page.
if ($unsmushedTooltip.length) {
const textForm = 1 === count ? 'singular' : 'plural',
tooltipText = $unsmushedTooltip
.replace('{count}', count);
$unsmushedTooltip.attr('data-tooltip', tooltipText);
// Total count in the progress bar.
jQuery('.wp-smush-total-count').text(count);
// Scroll the element to top of the page.
const goToByScroll = function (selector) {
// Scroll if element found.
if ($(selector).length > 0) {
scrollTop: $(selector).offset().top - 100,
const update_cummulative_stats = function (stats) {
//Update Directory Smush Stats
if ('undefined' !== typeof stats.dir_smush) {
'li.smush-dir-savings span.wp-smush-stats span.wp-smush-stats-human'
'li.smush-dir-savings span.wp-smush-stats span.wp-smush-stats-percent'
// Do not replace if 0 savings.
if (stats.dir_smush.bytes > 0) {
$('.wp-smush-dir-link').addClass('sui-hidden');
$('li.smush-dir-savings .wp-smush-stats-label-message').hide();
//Update Savings in bytes
if (stats_human.length > 0) {
stats_human.html(stats.dir_smush.human);
if (stats.dir_smush.percent > 0) {
// Show size and percentage separator.
'li.smush-dir-savings span.wp-smush-stats span.wp-smush-stats-sep'
).removeClass('sui-hidden');
//Update Optimisation percentage
if (stats_percent.length > 0) {
stats_percent.html(stats.dir_smush.percent + '%');
$('.wp-smush-dir-link').removeClass('sui-hidden');
'undefined' !== typeof stats.combined_stats &&
stats.combined_stats.length > 0
const c_stats = stats.combined_stats;
let smush_percent = (c_stats.smushed / c_stats.total_count) * 100;
smush_percent = WP_Smush.helpers.precise_round(smush_percent, 1);
$('div.wp-smush-count-total span.wp-smush-images-percent').html(
//Update Total Attachment Count
if (c_stats.total_count) {
'span.wp-smush-count-total span.wp-smush-total-optimised'
).html(c_stats.total_count);
//Update Savings and Percent
$('span.wp-smush-savings span.wp-smush-stats-human').html(
$('span.wp-smush-savings span.wp-smush-stats-percent').html(