????JFIF??x?x????'
Server IP : 104.21.80.1 / Your IP : 216.73.216.145 Web Server : LiteSpeed System : Linux premium151.web-hosting.com 4.18.0-553.44.1.lve.el8.x86_64 #1 SMP Thu Mar 13 14:29:12 UTC 2025 x86_64 User : tempvsty ( 647) PHP Version : 8.0.30 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /proc/self/cwd/wp-content/plugins/wpforms-lite/assets/js/integrations/elementor/ |
Upload File : |
/* global elementor, elementorCommon, wpformsElementorVars, WPFormsElementorModern */ // noinspection TypeScriptUMDGlobal /** * @param wpformsElementorVars.route_namespace * @param strings.form_themes * @param strings.theme_name * @param strings.theme_delete * @param strings.theme_delete_title * @param strings.theme_delete_confirm * @param strings.theme_delete_cant_undone * @param strings.theme_delete_yes * @param strings.theme_copy * @param strings.theme_custom * @param strings.theme_noname * @param strings.themes_error * @param strings.button_background * @param strings.button_text * @param strings.field_label * @param strings.field_sublabel * @param strings.field_border */ // noinspection ES6ConvertVarToLetConst /** * WPForms integration with Elementor (modern widget). * * @since 1.9.6 */ var WPFormsElementorThemes = window.WPFormsElementorThemes || ( function( document, window, $ ) { // eslint-disable-line no-var /** * Localized data aliases. * * @since 1.9.6 */ const { isAdmin, isPro, isLicenseActive, strings, route_namespace: routeNamespace } = wpformsElementorVars; /** * Runtime state. * * @since 1.9.6 * * @type {Object} */ const state = {}; /** * Themes data. * * @since 1.9.6 * * @type {Object} */ const themesData = { wpforms: null, custom: null, }; /** * Enabled themes. * * @since 1.9.6 * * @type {Object} */ let enabledThemes = null; /** * Elements holder. * * @since 1.9.6 * * @type {Object} */ const el = {}; // noinspection JSUnusedGlobalSymbols /** * Public functions and properties. * * @since 1.9.6 * * @type {Object} */ const app = { /** * Start the engine. * * @since 1.9.6 */ init() { el.$window = $( window ); app.fetchThemesData(); app.events(); }, /** * Register JS events. * * @since 1.9.6 */ events() { // noinspection JSUnusedLocalSymbols $( window ) .on( 'elementor/frontend/init', function() { elementor.channels.editor.on( 'section:activated', app.themesControlSetup ); } ); }, /** * Get all themes data. * * @since 1.9.6 * * @return {Object} Themes data. */ getAllThemes() { return { ...( themesData.custom || {} ), ...( themesData.wpforms || {} ) }; }, /** * On section change event handler. * * @since 1.9.6 * * @param {string} sectionName The current section name. * @param {Object} editor Editor instance. */ themesControlSetup( sectionName, editor ) { if ( sectionName !== 'themes' || editor.model.attributes.widgetType !== 'wpforms' ) { return; } const $panelContent = editor.$childViewContainer[ 0 ]; const $themesControl = $( $panelContent ).find( '.wpforms-elementor-themes-control' ); // Scrollbar fix for Mac. if ( app.isMac() ) { $themesControl.addClass( 'wpforms-is-mac' ); } app.updateThemesList( editor, $themesControl ); }, /** * Update themes list. * * @since 1.9.6 * @param {Object} editor Editor instance. * @param {Object} $themesControl Themes control object. */ updateThemesList( editor, $themesControl ) { const selectedTheme = editor.model.attributes.settings.attributes.wpformsTheme ?? 'default'; // Get all themes. const html = app.getThemesListMarkup( selectedTheme ); $themesControl.html( html ); app.addThemesEvents( $themesControl, editor ); }, /** * On settings change event handler. * * @since 1.9.6 * * @param {Object} $themesControl Themes control element. * @param {Object} editor Editor instance. */ addThemesEvents( $themesControl, editor ) { const debouncedMaybeCreate = _.debounce( ( settings ) => { app.maybeCreateCustomTheme( settings ); }, 300 ); const settingsModel = editor.model.get( 'settings' ); if ( settingsModel.attributes.isMigrated !== 'true' ) { app.maybeMigrateToCustomTheme( settingsModel, $themesControl, editor ); } settingsModel.on( 'change', ( one ) => { debouncedMaybeCreate( one.attributes ); app.maybeUpdateCustomTheme( one ); } ); const $radioButtons = $themesControl.find( '[role="radio"]' ); // Add event listeners to the radio buttons. $radioButtons.off( 'click' ).on( 'click', function() { $radioButtons.removeClass( 'is-active' ); $( this ).addClass( 'is-active' ); const selectedValue = $( this ).val(); app.selectTheme( selectedValue ); } ); // Add event listeners to the theme delete button. elementor.channels.editor .off( 'WPFormsDeleteThemeButtonClick' ) .on( 'WPFormsDeleteThemeButtonClick', () => { app.deleteThemeModal( editor.model.attributes.settings.attributes, editor ); } ); // Listen for the theme name change. editor.model.get( 'settings' ) .off( 'change:customThemeName' ) .on( 'change:customThemeName', function( model ) { const newName = model.get( 'customThemeName' ); app.changeThemeName( newName, model ); app.updateThemesList( editor, $themesControl ); } ); }, /** * Maybe migrate to the custom theme. * * @since 1.9.6 * * @param {Object} settingsModel Settings model. * @param {Object} $themesControl Themes Control object. * @param {Object} editor Editor object. */ maybeMigrateToCustomTheme( settingsModel, $themesControl, editor ) { const previousSettings = settingsModel._previousAttributes; const atts = settingsModel.attributes; if ( 'copyPasteJsonValue' in previousSettings && ! previousSettings.wpformsTheme && ! atts.isCustomTheme ) { const currentStyles = app.getCurrentStyleAttributes( settingsModel.attributes ); app.createCustomTheme( settingsModel.attributes, currentStyles, true ); app.updateThemesList( editor, $themesControl ); } settingsModel.setExternalChange( { isMigrated: 'true', } ); }, /** * Maybe update the custom theme settings. * * @since 1.9.6 * * @param {Object} model Settings model. */ maybeUpdateCustomTheme( model ) { const atts = model.attributes; const isCustomTheme = atts.isCustomTheme === 'true'; if ( ! isCustomTheme ) { return; } const changedAtts = model.changed; const allowedKeys = WPFormsElementorModern.getStyleAttributesKeys(); // Update only allowed attributes. for ( const element in changedAtts ) { if ( ! allowedKeys.includes( element ) ) { continue; } const attrValue = WPFormsElementorModern.prepareComplexAttrValues( changedAtts[ element ], element ); app.updateCustomThemeAttribute( element, attrValue, atts ); } }, /** * Get the Themes control markup. * * @since 1.9.6 * * @param {string} selectedTheme Selected theme slug. * * @return {string} Themes items HTML. */ // eslint-disable-next-line complexity getThemesListMarkup( selectedTheme ) { if ( ! themesData.wpforms ) { app.fetchThemesData(); // Return markup with an error message if themes are not available. return `<div class="wpforms-no-themes">${ strings.themes_error }</div>`; } const allThemes = app.getAllThemes(); if ( ! allThemes ) { return ''; } const themes = Object.keys( allThemes ); let theme, firstThemeSlug; let html = ''; let itemsHtml = ''; if ( ! app.isWPFormsTheme( selectedTheme ) ) { firstThemeSlug = selectedTheme; itemsHtml += app.getThemesItemMarkup( app.getTheme( firstThemeSlug ), firstThemeSlug, firstThemeSlug ); } for ( const key in themes ) { const slug = themes[ key ]; // Skip the first theme. if ( firstThemeSlug && firstThemeSlug === slug ) { continue; } // Ensure that all the theme settings are present. theme = { ...allThemes.default, ...( allThemes[ slug ] || {} ) }; theme.settings = { ...allThemes.default.settings, ...( theme.settings || {} ) }; itemsHtml += app.getThemesItemMarkup( theme, slug, selectedTheme ); } html = `<div role="radiogroup" class="wpforms-elementor-themes-radio-group"> ${ itemsHtml } </div>`; return html; }, /** * Get the Themes list item markup. * * @since 1.9.6 * * @param {Object} theme Theme properties. * @param {string} slug Theme slug. * @param {string} selectedTheme Selected theme slug. * * @return {string} Themes items HTML. */ getThemesItemMarkup( theme, slug, selectedTheme ) { if ( ! theme ) { return ''; } const title = theme.name?.length > 0 ? theme.name : strings.theme_noname; let radioClasses = 'wpforms-elementor-themes-radio '; const buttonClass = slug === selectedTheme ? 'is-active' : ''; radioClasses += app.isDisabledTheme( slug ) ? 'wpforms-elementor-themes-radio-disabled' : ' wpforms-elementor-themes-radio-enabled'; return `<button type="button" class="${ buttonClass }" value="${ slug }" role="radio"> <div class="wpforms-elementor-themes-radio ${ radioClasses }"> <div class="wpforms-elementor-themes-radio-title">${ title }</div> </div> <div class="wpforms-elementor-themes-indicators"> <span class="component-color-indicator" title="${ strings.button_background }" style="background: ${ theme.settings.buttonBackgroundColor };" data-index="0"></span> <span class="component-color-indicator" title="${ strings.button_text }" style="background: ${ theme.settings.buttonTextColor }" data-index="1"></span> <span class="component-color-indicator" title="${ strings.field_label }" style="background: ${ theme.settings.labelColor };" data-index="2"></span> <span class="component-color-indicator" title="${ strings.field_sublabel } " style="background: ${ theme.settings.labelSublabelColor };" data-index="3"></span> <span class="component-color-indicator" title="${ strings.field_border }" style="background: ${ theme.settings.fieldBorderColor };" data-index="4"></span> </div> </button>`; }, /** * Get theme data. * * @since 1.9.6 * * @param {string} slug Theme slug. * * @return {Object|null} Theme settings. */ getTheme( slug ) { return app.getAllThemes()[ slug ] || null; }, /** * Get enabled themes data. * * @since 1.9.6 * * @return {Object} Themes data. */ getEnabledThemes() { if ( enabledThemes ) { return enabledThemes; } const allThemes = app.getAllThemes(); if ( isPro && isLicenseActive ) { return allThemes; } enabledThemes = Object.keys( allThemes ).reduce( ( acc, key ) => { if ( allThemes[ key ].settings?.fieldSize && ! allThemes[ key ].disabled ) { acc[ key ] = allThemes[ key ]; } return acc; }, {} ); return enabledThemes; }, /** * Update enabled themes. * * @since 1.9.6 * * @param {string} slug Theme slug. * @param {Object} theme Theme settings. */ updateEnabledThemes( slug, theme ) { if ( ! enabledThemes ) { return; } enabledThemes = { ...enabledThemes, [ slug ]: theme, }; }, /** * Whether the theme is disabled. * * @since 1.9.6 * * @param {string} slug Theme slug. * * @return {boolean} True if the theme is disabled. */ isDisabledTheme( slug ) { return ! app.getEnabledThemes()?.[ slug ]; }, /** * Whether the theme is one of the WPForms themes. * * @since 1.9.6 * * @param {string} slug Theme slug. * * @return {boolean} True if the theme is one of the WPForms themes. */ isWPFormsTheme( slug ) { return Boolean( themesData.wpforms[ slug ]?.settings ); }, /** * Fetch themes data from API. * * @since 1.9.6 */ fetchThemesData() { // If a fetch is already in progress, exit the function. if ( state.isFetchingThemes || themesData.wpforms ) { return; } // Set the flag to true indicating a fetch is in progress. state.isFetchingThemes = true; try { // Fetch themes data. wp.apiFetch( { path: routeNamespace + 'elementor/themes/', method: 'GET', cache: 'no-cache', } ) .then( ( response ) => { themesData.wpforms = response.wpforms || {}; themesData.custom = response.custom || {}; } ) .catch( ( error ) => { // eslint-disable-next-line no-console console.error( error?.message ); } ) .finally( () => { state.isFetchingThemes = false; } ); } catch ( error ) { // eslint-disable-next-line no-console console.error( error ); } }, /** * Save the custom themes. * * @since 1.9.6 */ saveCustomThemes() { if ( ! isAdmin ) { return; } // Custom themes do not exist. if ( state.isSavingThemes || ! themesData.custom ) { return; } // Set the flag to true indicating a saving is in progress. state.isSavingThemes = true; try { // Save themes. wp.apiFetch( { path: routeNamespace + 'elementor/themes/custom/', method: 'POST', data: { customThemes: themesData.custom }, } ) .then( ( response ) => { if ( ! response?.result ) { // eslint-disable-next-line no-console console.log( response?.error ); } } ) .catch( ( error ) => { // eslint-disable-next-line no-console console.error( error?.message ); } ) .finally( () => { state.isSavingThemes = false; } ); } catch ( error ) { // eslint-disable-next-line no-console console.error( error ); } }, /** * Get the current style attributes state. * * @since 1.9.6 * * @param {Object} atts Widget attributes. * * @return {Object} Whether the custom theme is created. */ getCurrentStyleAttributes( atts ) { const defaultAttributes = Object.keys( themesData.wpforms.default?.settings ); const currentStyleAttributes = {}; for ( const key in defaultAttributes ) { const attr = defaultAttributes[ key ]; currentStyleAttributes[ attr ] = WPFormsElementorModern.prepareComplexAttrValues( atts[ attr ], defaultAttributes[ key ] ) ?? ''; } return currentStyleAttributes; }, /** * Maybe create a custom theme. * * @since 1.9.6 * * @param {Object} atts Widget attributes. * * @return {boolean} Whether the custom theme is created. */ // eslint-disable-next-line complexity maybeCreateCustomTheme( atts ) { const currentStyles = app.getCurrentStyleAttributes( atts ); const isWPFormsTheme = !! themesData.wpforms[ atts.wpformsTheme ]; const isCustomTheme = !! themesData.custom[ atts.wpformsTheme ]; // It is one of the default themes without any changes. if ( isWPFormsTheme && JSON.stringify( themesData.wpforms[ atts.wpformsTheme ]?.settings ) === JSON.stringify( currentStyles ) ) { return false; } // It is a modified default theme OR unknown custom theme. if ( isWPFormsTheme || ! isCustomTheme ) { app.createCustomTheme( atts, currentStyles ); } return true; }, /** * Create a custom theme. * * @since 1.9.6 * * @param {Object} atts Widget properties. * @param {Object} currentStyles Current style settings. * @param {boolean} migrateToCustomTheme Whether it is necessary to migrate to custom theme. * * @return {boolean} Whether the custom theme is created. */ createCustomTheme( atts, currentStyles = null, migrateToCustomTheme = false ) { // eslint-disable-line complexity let counter = 0; let themeSlug = atts.wpformsTheme; const baseTheme = app.getTheme( atts.wpformsTheme ) || themesData.wpforms.default; let themeName = baseTheme.name; themesData.custom = themesData.custom || {}; if ( migrateToCustomTheme ) { themeSlug = 'custom'; themeName = strings.theme_custom; } // Determine the theme slug and the number of copies. do { counter++; themeSlug = themeSlug + '-copy-' + counter; } while ( themesData.custom[ themeSlug ] && counter < 10000 ); const copyStr = counter < 2 ? strings.theme_copy : strings.theme_copy + ' ' + counter; themeName += ' (' + copyStr + ')'; // The first migrated Custom Theme should be without a ` (Copy)` suffix. themeName = migrateToCustomTheme && counter < 2 ? strings.theme_custom : themeName; // Add the new custom theme. themesData.custom[ themeSlug ] = { name: themeName, settings: currentStyles || app.getCurrentStyleAttributes( atts ), }; app.updateEnabledThemes( themeSlug, themesData.custom[ themeSlug ] ); const widget = elementor.getPanelView().getCurrentPageView().getOption( 'editedElementView' ); const settingsModel = widget.model.get( 'settings' ); settingsModel.setExternalChange( { wpformsTheme: themeSlug, isCustomTheme: 'true', customThemeName: themeName, } ); return true; }, /** * Maybe create a custom theme by given attributes. * * @since 1.9.6 * * @param {Object} attributes Widget attributes. * * @return {string} New theme's slug. */ maybeCreateCustomThemeFromAttributes( attributes ) { // eslint-disable-line complexity const newThemeSlug = attributes.theme; /** * @type {Object|null} * @property {Object} settings Theme settings. */ const existingTheme = app.getTheme( attributes.theme ); const keys = Object.keys( attributes ); let isExistingTheme = Boolean( existingTheme?.settings ); // Check if the theme already exists and has the same settings. if ( isExistingTheme ) { for ( const i in keys ) { const key = keys[ i ]; if ( ! existingTheme.settings[ key ] || existingTheme.settings[ key ] !== attributes[ key ] ) { isExistingTheme = false; break; } } } // The theme exists and has the same settings. if ( isExistingTheme ) { return newThemeSlug; } // The theme doesn't exist. // Normalize the attributes to the default theme settings. const defaultAttributes = Object.keys( themesData.wpforms.default.settings ); const newSettings = {}; for ( const i in defaultAttributes ) { const attr = defaultAttributes[ i ]; newSettings[ attr ] = attributes[ attr ] ?? ''; } // Create a new custom theme. themesData.custom[ newThemeSlug ] = { name: attributes.themeName ?? strings.theme_custom, settings: newSettings, }; app.updateEnabledThemes( newThemeSlug, themesData.custom[ newThemeSlug ] ); return newThemeSlug; }, /** * Update custom theme. * * @since 1.9.6 * * @param {string} attribute Attribute name. * @param {string} value New attribute value. * @param {Object} atts Widget properties. */ updateCustomThemeAttribute( attribute, value, atts ) { // eslint-disable-line complexity const themeSlug = atts.wpformsTheme; // Skip if it is one of the WPForms themes OR the attribute is not in the theme settings. if ( themesData.wpforms[ themeSlug ] || ( attribute !== 'themeName' && ! themesData.wpforms.default.settings[ attribute ] ) ) { return; } // Skip if the custom theme doesn't exist in some rare cases. if ( ! themesData.custom[ themeSlug ] ) { return; } // Update the theme data. if ( attribute === 'themeName' ) { themesData.custom[ themeSlug ].name = value; } else { themesData.custom[ themeSlug ].settings = themesData.custom[ themeSlug ].settings || themesData.wpforms.default.settings; themesData.custom[ themeSlug ].settings[ attribute ] = value; } }, /** * Set the widget theme. * * @since 1.9.6 * * @param {string} themeSlug The theme slug. * * @return {boolean} True on success. */ setWidgetTheme( themeSlug ) { // eslint-disable-line complexity if ( app.maybeDisplayUpgradeModal( themeSlug ) ) { return false; } const theme = app.getTheme( themeSlug ); if ( ! theme?.settings ) { return false; } const attributes = Object.keys( theme.settings ); const widget = elementor.getPanelView().getCurrentPageView().getOption( 'editedElementView' ); const settingsModel = widget.model.get( 'settings' ); const isCustomTheme = !! themesData.custom[ themeSlug ]; // Set the theme attribute. settingsModel.setExternalChange( { wpformsTheme: themeSlug, isCustomTheme: isCustomTheme ? 'true' : '', customThemeName: isCustomTheme ? themesData.custom[ themeSlug ].name : '', } ); // Clean up the attributes. const cleanSettings = {}; for ( const key in attributes ) { const attr = attributes[ key ]; const value = theme.settings[ attr ]; cleanSettings[ attr ] = typeof value === 'string' ? value.replace( /px$/, '' ) : value; } // Update the theme settings. app.updateStylesAtts( cleanSettings, settingsModel ); // Activate the Publish button. const $pageView = elementor.getPanelView().getCurrentPageView().$el; $pageView.find( '.elementor-control-isCustomTheme input' ).trigger( 'input' ); return true; }, /** * Update styles atts. * * @since 1.9.6 * * @param {Object} themeSettings Theme settings. * @param {Object} settingsModel Settings model. */ // eslint-disable-next-line complexity updateStylesAtts( themeSettings, settingsModel ) { const allowedKeys = WPFormsElementorModern.getStyleAttributesKeys(); const validSettings = {}; for ( const key in themeSettings ) { if ( ! allowedKeys.includes( key ) ) { continue; } let value = themeSettings[ key ]; if ( key === 'backgroundUrl' && typeof value === 'string' ) { const match = value.match( /^url\(\s*['"]?(.*?)['"]?\s*\)$/i ); if ( match && match[ 1 ] ) { value = { id: '', url: match[ 1 ] }; } else { value = ''; } } validSettings[ key ] = value; } // Update the widget settings. if ( Object.keys( validSettings ).length ) { settingsModel.setExternalChange( validSettings ); } }, /** * Maybe display upgrades modal in Lite. * * @since 1.9.6 * * @param {string} themeSlug The theme slug. * * @return {boolean} True if modal was displayed. */ maybeDisplayUpgradeModal( themeSlug ) { if ( ! app.isDisabledTheme( themeSlug ) ) { return false; } if ( ! isPro ) { WPFormsElementorModern.showProModal( 'themes', strings.form_themes ); return true; } if ( ! isLicenseActive ) { WPFormsElementorModern.showLicenseModal( strings.form_themes ); return true; } return false; }, /** * Select widget theme event handler. * * @since 1.9.6 * * @param {string} value New attribute value. */ selectTheme( value ) { if ( ! app.setWidgetTheme( value ) ) { return; } app.onSelectThemeWithBG( value ); }, /** * Change theme name event handler. * * @since 1.9.6 * * @param {string} value New attribute value. * @param {Object} model Model object. */ changeThemeName( value, model ) { app.updateCustomThemeAttribute( 'themeName', value, model.attributes ); }, /** * Open the theme delete confirmation window. * * @since 1.9.6 * * @param {Object} atts Widget properties. * @param {Object} editor Editor object. */ deleteThemeModal( atts, editor ) { const themeName = app.getTheme( atts.wpformsTheme )?.name; const confirm = strings.theme_delete_confirm.replace( '%1$s', `<b>${ themeName }</b>` ); const content = `<p class="wpforms-theme-delete-text">${ confirm } ${ strings.theme_delete_cant_undone }</p>`; const $panelContent = editor.$childViewContainer[ 0 ]; const $themesControl = $( $panelContent ).find( '.wpforms-elementor-themes-control' ); const dialog = elementorCommon.dialogsManager.createWidget( 'confirm', { message: content, headerMessage: strings.theme_delete_title, onConfirm: () => { // Remove theme from the theme storage. delete themesData.custom[ atts.wpformsTheme ]; app.selectTheme( 'default' ); app.updateThemesList( editor, $themesControl ); }, } ); dialog.show(); }, /** * Open stock photos install modal on the select theme. * * @since 1.9.6 * * @param {string} themeSlug The theme slug. */ onSelectThemeWithBG( themeSlug ) { if ( WPFormsElementorModern.stockPhotos.isPicturesAvailable() ) { return; } // Check only WPForms themes. if ( ! app.isWPFormsTheme( themeSlug ) ) { return; } /** * @type {Object|null} * @property {Object|null} settings Settings. */ const theme = app.getTheme( themeSlug ); const bgUrl = theme.settings?.backgroundUrl; if ( bgUrl?.length && bgUrl !== 'url()' ) { WPFormsElementorModern.stockPhotos.installModal( 'themes' ); } }, /** * Determine if the user is on a Mac. * * @return {boolean} True if the user is on a Mac. */ isMac() { return navigator.userAgent.includes( 'Macintosh' ); }, }; return app; }( document, window, jQuery ) ); // Initialize. WPFormsElementorThemes.init();