: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
import tracker from "../utils/tracker";
* Modals JavaScript code.
membership: 'free', // Assume free by default.
onboardingModal: document.getElementById( 'smush-onboarding-dialog' ),
contentContainer: document.getElementById( 'smush-onboarding-content' ),
if ( ! this.onboardingModal ) {
const dialog = document.getElementById( 'smush-onboarding' );
this.membership = dialog.dataset.type;
this.recheckImagesLink = dialog.dataset.ctaUrl;
if ( 'pro' !== this.membership ) {
this.onboardingSlides = [
if ( 'false' === dialog.dataset.tracking ) {
this.onboardingSlides.pop();
const skipButton = this.onboardingModal.querySelector(
'.smush-onboarding-skip-link'
skipButton.addEventListener( 'click', this.skipSetup.bind( this ) );
'smush-onboarding-dialog',
const firstTouch = e.touches[ 0 ];
this.touchX = firstTouch.clientX;
this.touchY = firstTouch.clientY;
* Process swipe left/right.
if ( ! this.touchX || ! this.touchY ) {
const xUp = e.touches[ 0 ].clientX,
yUp = e.touches[ 0 ].clientY,
xDiff = this.touchX - xUp,
yDiff = this.touchY - yUp;
if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {
if ( false === WP_Smush.onboarding.settings.last ) {
WP_Smush.onboarding.next( null, 'next' );
} else if ( false === WP_Smush.onboarding.settings.first ) {
WP_Smush.onboarding.next( null, 'prev' );
* Update the template, register new listeners.
* @param {string} directionClass Accepts: fadeInRight, fadeInLeft, none.
renderTemplate( directionClass = 'none' ) {
// Grab the selected value.
const input = this.onboardingModal.querySelector(
this.selection[ input.id ] = input.checked;
const template = WP_Smush.onboarding.template( 'smush-onboarding' );
const content = template( this.settings );
this.contentContainer.innerHTML = content;
if ( 'none' === directionClass ) {
this.contentContainer.classList.add( 'loaded' );
this.contentContainer.classList.remove( 'loaded' );
this.contentContainer.classList.add( directionClass );
this.contentContainer.classList.add( 'loaded' );
this.contentContainer.classList.remove(
this.onboardingModal.addEventListener(
this.onboardingModal.addEventListener(
* Catch "Finish setup wizard" button click.
const submitButton = this.onboardingModal.querySelector(
submitButton.addEventListener( 'click', function( e ) {
// Because we are not rendering the template, we need to update the last element value.
const input = self.onboardingModal.querySelector(
self.selection[ input.id ] = input.checked;
const _nonce = document.getElementById(
'smush_quick_setup_nonce'
const xhr = new XMLHttpRequest();
xhr.open( 'POST', ajaxurl + '?action=smush_setup', true );
'application/x-www-form-urlencoded'
if ( 200 === xhr.status ) {
'Request failed. Returned status of ' +
JSON.stringify( self.selection ) +
this.startRecheckImages();
if ( ! this.recheckImagesLink ) {
window.location.href = this.recheckImagesLink;
* @param {null|string} whereTo
next( e, whereTo = null ) {
const index = this.onboardingSlides.indexOf( this.settings.slide );
null !== e && e.classList.contains( 'next' )
newIndex = 'next' === whereTo ? index + 1 : index - 1;
null !== e && e.classList.contains( 'next' )
last: newIndex + 1 === this.onboardingSlides.length, // length !== index
slide: this.onboardingSlides[ newIndex ],
value: this.selection[ this.onboardingSlides[ newIndex ] ],
this.renderTemplate( directionClass );
* Handle circle navigation.
const newIndex = this.onboardingSlides.indexOf( target );
last: newIndex + 1 === this.onboardingSlides.length, // length !== index
value: this.selection[ target ],
* Skip onboarding experience.
const _nonce = document.getElementById( 'smush_quick_setup_nonce' );
const xhr = new XMLHttpRequest();
ajaxurl + '?action=skip_smush_setup&_ajax_nonce=' + _nonce.value
if ( 200 === xhr.status ) {
'Request failed. Returned status of ' + xhr.status
* Hide new features modal.
* @since 3.12.2 Add a new parameter redirectUrl
hideUpgradeModal: ( e, button ) => {
button.classList.add( 'wp-smush-link-in-progress' );
const redirectUrl = button?.href;
const xhr = new XMLHttpRequest();
xhr.open( 'POST', ajaxurl + '?action=hide_new_features&_ajax_nonce=' + window.wp_smush_msgs.nonce );
button.classList.remove( 'wp-smush-link-in-progress' );
const actionName = redirectUrl ? 'cta_clicked' : 'closed';
tracker.track( 'update_modal_displayed', {
if ( 200 === xhr.status ) {
window.location.href = redirectUrl;
'Request failed. Returned status of ' + xhr.status
* Template function (underscores based).
WP_Smush.onboarding.template = _.memoize( ( id ) => {
evaluate: /<#([\s\S]+?)#>/g,
interpolate: /{{{([\s\S]+?)}}}/g,
escape: /{{([^}]+?)}}(?!})/g,
_.templateSettings = options;
_.template( document.getElementById( id ).innerHTML );
data.first_slide = WP_Smush.onboarding.first_slide;
window.addEventListener( 'load', () => WP_Smush.onboarding.init() );