${ window.wp.escapeHtml.escapeHTML( contrastMessage ) }
` );
} );
},
/**
* Callback for input changes.
* This method is used to update the preview URL.
*
* @since 1.8.6
*/
handleOnPreviewChanges() {
// Bail if the XOR encryption is not available.
if ( ! window.WPFormsXOR ) {
return;
}
// Get the current input.
const $this = $( this );
// Extract the 'name' attribute.
const name = $this.attr( 'name' );
// Extract the ID from the 'name' attribute using a regex.
// Explanation:
// - /\[([^[\]]+)]/i: Match square brackets and capture the content inside.
// - ( || [] )[1]: Use the captured content, or an empty array if not found.
// - || name: If still not found, fallback to the original 'name'.
// - replace(/-/g, '_'): Replace dashes with underscores in the ID.
const id = ( ( name.match( /\[([^[\]]+)]/i ) || [] )[ 1 ] || name ).replace( /-/g, '_' );
// Get the current input value.
const value = $this.val();
// Destructure utility functions from the wp.url object.
const { isURL, addQueryArgs, getQueryArg } = wp.url;
// Query argument name.
const queryArgName = 'wpforms_email_style_overrides';
// Create an XOR instance.
const xorInstance = new window.WPFormsXOR();
// Filter and update the href attribute for elements with class 'wpforms-btn-preview'.
$( '.wpforms-btn-preview' )
.filter( ( index, elm ) => isURL( $( elm ).attr( 'href' ) ) )
.attr( 'href', ( index, oldHref ) => {
const existingOverrides = xorInstance.decrypt( getQueryArg( oldHref, queryArgName ) );
const updatedOverrides = { ...existingOverrides, [ id ]: value };
const updatedQueryString = xorInstance.encrypt( updatedOverrides );
return addQueryArgs( oldHref, { [ queryArgName ]: updatedQueryString } );
} );
},
/**
* Callback for the appearance mode toggle.
*
* @since 1.8.6
*/
handleOnAppearanceModeToggle() {
// Reference to the clicked radio button.
const $this = $( this );
// Define class names for elements.
const { hide: hideClassName, settingField: settingFieldClassName } = vars.classNames;
// Get the value of the selected radio button.
const selected = $this.val();
// Find the closest setting field container.
const $settingField = $this.closest( `.${ settingFieldClassName }` );
// Find the unselected radio button within the same setting field.
const $unselectedInput = $settingField.find( 'input:not(:checked)' );
// Get the value of the unselected radio button.
const unselected = $unselectedInput.val();
$( `.email-${ selected }-mode` ).removeClass( hideClassName );
$( `.email-${ unselected }-mode` ).addClass( hideClassName );
},
/**
* Relocate image size select input for styling purposes.
*
* @since 1.8.5
*/
relocateImageSize() {
const $imgSize = $( '.wpforms-email-header-image-size' );
// Bail if there is no "Remove Image" button.
if ( $imgSize.length === 0 ) {
return;
}
$imgSize.each( ( index, elm ) => {
const $this = $( elm );
const $select = $this.find( 'select' );
// Bail if there is no select element.
if ( $select.length === 0 ) {
return;
}
// Get the header image element.
const $headerImage = $this.prev();
// Move the select element before the "Remove Image" button.
$headerImage.find( '.wpforms-setting-remove-image' ).before( $select.get( 0 ).outerHTML );
// Remove the original select element.
$select.remove();
try {
// Cache the new select input.
const $newSelect = $headerImage.find( 'select' );
// Add the image size class. Note that the default value is 140.
$headerImage.addClass( `has-image-size-${ $newSelect.val() || 'medium' }` );
// Bind the change event, and update the image size class.
$newSelect.on( 'change', app.handleOnUpdateImageSize );
// Initialize Choices.
new Choices( $newSelect.get( 0 ), {
searchEnabled: false,
shouldSort: false,
} );
// Check if it's a legacy template and adjust settings accordingly.
if ( app.isLegacyTemplate() ) {
el.$wrapper.find( `.${ vars.classNames.noticeLegacy }` ).show();
$headerImage.find( '.choices' ).hide();
}
} catch ( e ) {
// Handle any potential errors, but continue execution.
// eslint-disable-next-line no-console
console.error( 'Error during relocation:', e );
}
} );
},
/**
* Determine whether the currently selected template is the "Legacy" template.
* Legacy template is the one that its value is 'default'.
*
* @since 1.8.6
*
* @return {boolean} True if the current template is legacy.
*/
isLegacyTemplate() {
return el.$wrapper.find( '.wpforms-setting-row-email_template input:checked' ).val() === 'default';
},
/**
* Get background colors for light and dark modes.
*
* This function retrieves the visible background color or falls back to the default one
* for both light and dark modes.
*
* @since 1.8.6
*
* @return {Array} An array containing background colors for light and dark modes.
*/
getBackgroundColors() {
// Get the visible background color or the default one.
const getVisibleBackgroundColor = ( selector, fallbackSelector ) => {
const visibleColor = el.$wrapper.find( `${ selector }:visible` ).val();
return visibleColor || el.$wrapper.find( fallbackSelector ).val();
};
// Return an array of background colors for light and dark modes.
return [
getVisibleBackgroundColor( ...vars.cache.colors.light.background ),
getVisibleBackgroundColor( ...vars.cache.colors.dark.background ),
];
},
/**
* Sync the background color value.
*
* @since 1.8.6
*
* @param {string} lightBackgroundColor The light background color in hex format.
* @param {string} darkBackgroundColor The dark background color in hex format.
*/
syncBackgroundColors( lightBackgroundColor, darkBackgroundColor ) {
// Bail if there is no light or dark background color.
if ( ! lightBackgroundColor || ! darkBackgroundColor ) {
return;
}
// Define color arrays for different elements.
const backgrounds = [
vars.cache.colors.light.background,
vars.cache.colors.dark.background,
];
// Reflect the change in the color picker.
for ( let i = 0; i < backgrounds.length; i++ ) {
// Determine the color based on the loop index.
const color = i === 0 ? lightBackgroundColor : darkBackgroundColor;
// Select the corresponding image element based on the loop index.
const $img = i === 0 ? $( '#wpforms-setting-row-email-header-image' ) : $( '#wpforms-setting-row-email-header-image-dark' );
// Iterate over elements in the current color array.
backgrounds[ i ].forEach( ( selector ) => {
// Find the element using the selector.
const $background = el.$wrapper.find( selector );
// Set the color value for the element.
$background.val( color );
// Update the background color in the color picker swatch.
$background.next().find( '.minicolors-swatch-color' ).css( 'backgroundColor', color );
} );
// Update the background color for the image element.
$img.find( 'img' ).css( 'backgroundColor', color );
}
},
};
// Provide access to public functions/properties.
return app;
}( document, window, jQuery, wpforms_admin_email_settings ) );
// Initialize.
WPFormsEmailSettings.init();