HEX
Server: Apache/2
System: Linux server-80-13-140-150.da.direct 5.14.0-362.24.1.el9_3.0.1.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Apr 4 22:31:43 UTC 2024 x86_64
User: cpt (1004)
PHP: 8.1.24
Disabled: exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Upload Files
File: /home/cpt/public_html/wp-content/plugins/wpforms-captcha/assets/js/admin-builder-captcha.js
/* global wpforms_builder_custom_captcha, wpforms_builder, WPFormsBuilder */

/**
 * WPForms Custom Captcha admin builder function.
 *
 * @since 1.1.0
 */

'use strict';

var WPFormsCaptcha = window.WPFormsCaptcha || ( function( document, window, $ ) {

	/**
	 * Public functions and properties.
	 *
	 * @since 1.1.0
	 *
	 * @type {object}
	 */
	var app = {

		/**
		 * Document events on which removeEmptyQuestions() should be fired.
		 *
		 * @since 1.6.0
		 */
		removeEmptyQuestionsEvents: 'wpformsPanelSwitch wpformsFieldTabToggle wpformsFieldOptionGroupToggle',

		/**
		 * Start the engine.
		 *
		 * @since 1.1.0
		 */
		init: function() {

			$( app.ready );
		},

		/**
		 * Initialize once the DOM is fully loaded.
		 *
		 * @since 1.1.0
		 */
		ready: function() {

			$( '#wpforms-builder' )

				// Type (format) toggle.
				.on( 'change', '.wpforms-field-option-captcha .wpforms-field-option-row-format select', app.formatToggle )

				// Add new captcha question.
				.on( 'click', '.wpforms-field-option-row-questions .add', app.addQuestion )

				// Remove captcha question.
				.on( 'click', '.wpforms-field-option-row-questions .remove', app.removeQuestion )

				// Captcha sample question update.
				.on( 'input', '.wpforms-field-option-row-questions .question', app.updateQuestion )

				// Captcha sample answer update.
				.on( 'input', '.wpforms-field-option-row-questions .answer', app.updateAnswer )

				// Remove empty questions before saving the form.
				.on( 'wpformsBeforeSave', app.removeEmptyQuestions );

			// Validate questions before panel switch and field tab toggle.
			$( document ).on( app.removeEmptyQuestionsEvents, app.removeEmptyQuestions );
		},

		/**
		 * Format toggle event handler.
		 *
		 * @since 1.3.2
		 */
		formatToggle: function() {

			var $this      = $( this ),
				value      = $this.val(),
				id         = $this.parent().data( 'field-id' ),
				$questions = $( '#wpforms-field-option-row-' + id + '-questions' ),
				$size      = $( '#wpforms-field-option-row-' + id + '-size' );

			if ( value === 'math' ) {
				$questions.hide().addClass( 'wpforms-hidden' );
				$size.hide();
			} else {
				$questions.show().removeClass( 'wpforms-hidden' );
				$size.show();
			}
		},

		/**
		 * Add new captcha question event handler.
		 *
		 * @since 1.3.2
		 *
		 * @param {object} event Event object.
		 */
		addQuestion: function( event ) {

			event.preventDefault();

			var $this        = $( this ),
				$choice      = $this.closest( 'li' ),
				$choicesList = $this.closest( '.choices-list' ),
				fieldID      = $choicesList.data( 'field-id' ),
				id           = $choicesList.attr( 'data-next-id' ),
				$question    = $choice.clone().insertAfter( $choice ),
				name         = 'fields[' + fieldID + '][questions][' + id + ']';

			$question.attr( 'data-key', id );
			$question.find( 'input.question' ).val( '' ).attr( 'name', name + '[question]' );
			$question.find( 'input.answer' ).val( '' ).attr( 'name', name + '[answer]' );
			$choicesList.attr( 'data-next-id', ++id );
		},

		/**
		 * Remove captcha question event handler.
		 *
		 * @since 1.3.2
		 *
		 * @param {object} event Event object.
		 */
		removeQuestion: function( event ) {

			event.preventDefault();

			var $this        = $( this ),
				$choice      = $this.closest( 'li' ),
				$choicesList = $this.closest( '.choices-list' ),
				$questions   = $choicesList.find( '.question' ),
				fieldID      = $choicesList.data( 'field-id' ),
				total        = app.getTotalNotEmptyQuestions( $questions );

			// We can delete a choice if at least one non-empty question will remain.
			if (
				total > 1 ||
				( total === 1 && $choice.find( '.question' ).val().trim().length === 0 )
			) {
				$choice.remove();
				$( '#wpforms-field-' + fieldID ).find( '.wpforms-question' ).text( $choicesList.find( '.question' ).val() );

				return;
			}

			app.showAlert( null );
		},

		/**
		 * Remove questions with empty question or answer values before saving the form.
		 *
		 * @since 1.5.0
		 *
		 * @param {Event} event The `wpformsBeforeSave` event object.
		 */
		removeEmptyQuestions: function( event ) {

			const $captchaFields = $( '.wpforms-field-option-captcha' );

			$captchaFields.each( function( _fieldIndex, field ) {

				const id               = $( field ).data( 'field-id' );
				const $choicesList     = $( '#wpforms-field-option-row-' + id + '-questions .choices-list' );
				const $choices         = $choicesList.find( 'li' );
				const $notEmptyChoices = app.getNotEmptyChoices( $choices );

				// If all choices are considered empty, show and alert and stop.
				if ( $notEmptyChoices.length === 0 ) {

					app.showAlert( function() {

						const currentAlert = this.$el;

						// Close any other popups if active. The main goal is to close Marketing Panel popup.
						$( '.jconfirm' ).map( function() {
							const $jConfirm = $( this );
							if ( ! $( currentAlert ).is( $jConfirm ) ) {
								$jConfirm.find( '.btn-default' ).trigger( 'click' );
							}
						} );

						$( document ).off( app.removeEmptyQuestionsEvents, app.removeEmptyQuestions );

						// We're not on Fields panel, activate it.
						if ( $( '#wpforms-panels-toggle .active' ).data( 'panel' ) !== 'fields' ) {
							WPFormsBuilder.panelSwitch( 'fields' );
						}

						// Activate Field Options > General.
						WPFormsBuilder.fieldTabToggle( id );
						$( '#wpforms-field-option-' + id + ' .wpforms-field-option-group' ).removeClass( 'active' );
						$( '#wpforms-field-option-basic-' + id ).addClass( 'active' );

						$( document ).on( app.removeEmptyQuestionsEvents, app.removeEmptyQuestions );
					} );

					// Stop saving the form.
					event.preventDefault();

					return;
				}

				// We're good to go, let's remove empty choices.
				$choices.each( function( _choiceIndex, choice ) {

					const $choice = $( choice );

					if ( app.isEmptyChoice( $choice ) ) {
						$choice.remove();
					}
				} );

				// Update preview, if needed.
				$( '#wpforms-field-' + id ).find( '.wpforms-question' ).text( $choices.find( '.question' ).val() );
			} );
		},

		/**
		 * Captcha sample question update event handler.
		 *
		 * @since 1.3.2
		 */
		updateQuestion: function() {

			const $this      = $( this ),
				$choicesList = $this.closest( '.choices-list' ),
				$questions   = $choicesList.find( '.question' ),
				fieldID      = $choicesList.data( 'field-id' ),
				value        = $this.val().trim();

			$this.toggleClass( 'wpforms-error', ! value.length );

			if ( ! value.length ) {
				return;
			}

			$this.data( 'prev-value', value );

			if ( $this.is( $questions[0] ) ) {
				$( '#wpforms-field-' + fieldID ).find( '.wpforms-question' ).text( value );
			}
		},

		/**
		 * Captcha sample answer update event handler.
		 *
		 * @since 1.6.0
		 */
		updateAnswer: function() {

			const $this      = $( this ),
				value        = $this.val().trim();

			$this.toggleClass( 'wpforms-error', ! value.length );
		},

		/**
		 * Show alert notifying that at least one not empty choice should remain.
		 *
		 * @since 1.3.2
		 *
		 * @param {Function|null} action Callback action attached to the confirm button.
		 */
		showAlert: function( action ) {

			$.alert( {
				title:   false,
				content: wpforms_builder_custom_captcha.error_not_empty_question,
				icon:   'fa fa-exclamation-circle',
				type:   'orange',
				buttons: {
					confirm: {
						text:     wpforms_builder.ok,
						btnClass: 'btn-confirm',
						keys:     [ 'enter' ],
						action:   action,
					},
				},
			} );
		},

		/**
		 * Count all non-empty questions.
		 *
		 * @since 1.3.2
		 *
		 * @param {jQuery} $questions Questions choices jQuery object.
		 *
		 * @returns {number} Number of total not empty questions.
		 */
		getTotalNotEmptyQuestions: function( $questions ) {

			return $questions.filter( function() {

				return this.value.trim().length;
			} ).length;
		},

		/**
		 * Filter out all choices that have either empty question or empty answer.
		 *
		 * @since 1.5.0
		 *
		 * @param {jQuery} $choices All question/answer choices.
		 *
		 * @returns {jQuery} Choices containing only non-empty question and answer.
		 */
		getNotEmptyChoices( $choices ) {

			return $choices.filter( function() {

				return ! app.isEmptyChoice( $( this ) );
			} );
		},

		/**
		 * Determine whether a question/answer choice is empty.
		 * A choice is considered "empty" if either question or answer is empty.
		 *
		 * @since 1.5.0
		 *
		 * @param {jQuery} $choice List item containing both question and answer fields.
		 *
		 * @returns {boolean} Whether the choice is empty.
		 */
		isEmptyChoice( $choice ) {

			return $choice.find( '.question' ).val().trim().length === 0 || $choice.find( '.answer' ).val().trim().length === 0;
		},
	};

	// Provide access to public functions/properties.
	return app;

}( document, window, jQuery ) );

// Initialize.
WPFormsCaptcha.init();