Add massive collection of CSS, JavaScript and theme assets that were previously excluded: **CSS Files (681 total):** - HVAC plugin-specific styles (hvac-*.css): 34 files including dashboard, certificates, registration, mobile nav, accessibility fixes, animations, and welcome popup - Theme framework files (Astra, builder systems, layouts): 200+ files - Plugin compatibility styles (WooCommerce, WPForms, Elementor, Contact Form 7): 150+ files - WordPress core and editor styles: 50+ files - Responsive and RTL language support: 200+ files **JavaScript Files (400+ total):** - HVAC plugin functionality (hvac-*.js): 27 files including menu systems, dashboard enhancements, profile sharing, mobile responsive features, accessibility, and animations - Framework and library files: jQuery plugins, GSAP, AOS, Swiper, Chart.js, Lottie, Isotope - Plugin compatibility scripts: WPForms, WooCommerce, Elementor, Contact Form 7, LifterLMS - WordPress core functionality: customizer, admin, block editor compatibility - Third-party integrations: Stripe, SMTP, analytics, search functionality **Assets:** - Certificate background images and logos - Comprehensive theme styling infrastructure - Mobile-responsive design systems - Cross-browser compatibility assets - Performance-optimized minified versions **Updated .gitignore:** - Fixed asset directory whitelisting patterns to properly include CSS/JS/images - Added proper directory structure recognition (!/assets/css/, !/assets/js/, etc.) - Maintains security by excluding sensitive files while including essential assets This commit provides the complete frontend infrastructure needed for: - Full theme functionality and styling - Plugin feature implementations - Mobile responsiveness and accessibility - Cross-browser compatibility - Performance optimization - Developer workflow support
		
			
				
	
	
		
			229 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			229 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* global wpforms_builder, Choices, wpf */
 | |
| 
 | |
| /**
 | |
|  * WPForms ChoicesJS utility methods for the Admin Builder.
 | |
|  *
 | |
|  * @since 1.7.9
 | |
|  */
 | |
| 
 | |
| 'use strict';
 | |
| 
 | |
| var WPForms = window.WPForms || {};
 | |
| 
 | |
| WPForms.Admin = WPForms.Admin || {};
 | |
| WPForms.Admin.Builder = WPForms.Admin.Builder || {};
 | |
| 
 | |
| WPForms.Admin.Builder.WPFormsChoicesJS = WPForms.Admin.Builder.WPFormsChoicesJS || ( function( document, window, $ ) {
 | |
| 
 | |
| 	/**
 | |
| 	 * Public functions and properties.
 | |
| 	 *
 | |
| 	 * @since 1.7.9
 | |
| 	 *
 | |
| 	 * @type {object}
 | |
| 	 */
 | |
| 	const app = {
 | |
| 
 | |
| 		/**
 | |
| 		 * Setup the Select Page ChoicesJS instance.
 | |
| 		 *
 | |
| 		 * @since 1.7.9
 | |
| 		 *
 | |
| 		 * @param {object}  element       DOM Element where to init ChoicesJS.
 | |
| 		 * @param {object}  choicesJSArgs ChoicesJS init options.
 | |
| 		 * @param {object}  ajaxArgs      Object containing `action` and `nonce` to perform AJAX search.
 | |
| 		 *
 | |
| 		 * @returns {Choices} ChoicesJS instance.
 | |
| 		 */
 | |
| 		setup: function( element, choicesJSArgs, ajaxArgs ) {
 | |
| 
 | |
| 			choicesJSArgs.searchEnabled = true;
 | |
| 			choicesJSArgs.allowHTML = false; // TODO: Remove after next Choices.js release.
 | |
| 			choicesJSArgs.searchChoices = ajaxArgs.nonce === null; // Enable searchChoices when not using AJAX.
 | |
| 			choicesJSArgs.renderChoiceLimit = -1;
 | |
| 			choicesJSArgs.noChoicesText = choicesJSArgs.noChoicesText || wpforms_builder.no_pages_found;
 | |
| 			choicesJSArgs.noResultsText = choicesJSArgs.noResultsText || wpforms_builder.no_pages_found;
 | |
| 
 | |
| 			const choicesJS = new Choices( element, choicesJSArgs );
 | |
| 
 | |
| 			if ( ajaxArgs.nonce === null ) {
 | |
| 				return choicesJS;
 | |
| 			}
 | |
| 
 | |
| 			$( element ).data( 'choicesjs', choicesJS );
 | |
| 
 | |
| 			/*
 | |
| 			 * ChoicesJS doesn't handle empty string search with it's `search` event handler,
 | |
| 			 * so we work around it by detecting empty string search with `keyup` event.
 | |
| 			 */
 | |
| 			choicesJS.input.element.addEventListener( 'keyup', function( ev ) {
 | |
| 
 | |
| 				// Only capture backspace and delete keypress that results to empty string.
 | |
| 				if (
 | |
| 					( ev.which !== 8 && ev.which !== 46 ) ||
 | |
| 					ev.target.value.length > 0
 | |
| 				) {
 | |
| 					return;
 | |
| 				}
 | |
| 
 | |
| 				app.performSearch( choicesJS, '', ajaxArgs );
 | |
| 			} );
 | |
| 
 | |
| 			choicesJS.passedElement.element.addEventListener( 'search', _.debounce( function( ev ) {
 | |
| 
 | |
| 				// Make sure that the search term is actually changed.
 | |
| 				if ( choicesJS.input.element.value.length === 0 ) {
 | |
| 					return;
 | |
| 				}
 | |
| 
 | |
| 				app.performSearch( choicesJS, ev.detail.value, ajaxArgs );
 | |
| 			}, 800 ) );
 | |
| 
 | |
| 			choicesJS.passedElement.element.addEventListener( 'change', function() {
 | |
| 				const select = $( this ),
 | |
| 					fieldId = select.data( 'field-id' ),
 | |
| 					fieldName = select.data( 'field-name' ),
 | |
| 					value = choicesJS.getValue();
 | |
| 
 | |
| 				const selected = value.map( function( item ) {
 | |
| 					return item.value;
 | |
| 				} );
 | |
| 
 | |
| 				const $hidden = $( `#wpforms-field-${ fieldId }-${ fieldName }-select-multiple-options` );
 | |
| 
 | |
| 				$hidden.val( JSON.stringify( selected ) );
 | |
| 			} );
 | |
| 
 | |
| 			// Add ability to close the drop-down menu.
 | |
| 			choicesJS.containerOuter.element.addEventListener( 'click', function() {
 | |
| 				if ( $( this ).hasClass( 'is-open' ) ) {
 | |
| 					choicesJS.hideDropdown();
 | |
| 				}
 | |
| 			} );
 | |
| 
 | |
| 			// Show more button for choices after the group is toggled.
 | |
| 			$( document )
 | |
| 				.on( 'wpformsFieldOptionGroupToggled', function() {
 | |
| 					wpf.showMoreButtonForChoices( choicesJS.containerOuter.element );
 | |
| 				} )
 | |
| 				.on( 'wpformsBeforeFieldDuplicate', function( event, id ) {
 | |
| 					if ( $( element ).data( 'field-id' ) !== id ) {
 | |
| 						return;
 | |
| 					}
 | |
| 
 | |
| 					const choices = choicesJS.getValue( true );
 | |
| 
 | |
| 					$( element ).data( 'choicesjs' ).destroy();
 | |
| 
 | |
| 					$( element ).find( 'option' ).each( function( index, option ) {
 | |
| 						if ( choices.includes( $( option ).val() ) ) {
 | |
| 							$( option ).prop( 'selected', true );
 | |
| 						}
 | |
| 					} );
 | |
| 				} )
 | |
| 				.on( 'wpformsFieldDuplicated', function( event, id ) {
 | |
| 					if ( $( element ).data( 'field-id' ) !== id ) {
 | |
| 						return;
 | |
| 					}
 | |
| 
 | |
| 					$( element ).data( 'choicesjs' ).init();
 | |
| 				} );
 | |
| 
 | |
| 			return choicesJS;
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Perform search in ChoicesJS instance.
 | |
| 		 *
 | |
| 		 * @since 1.7.9
 | |
| 		 *
 | |
| 		 * @param {Choices} choicesJS  ChoicesJS instance.
 | |
| 		 * @param {string}  searchTerm Search term.
 | |
| 		 * @param {Object}  ajaxArgs   Object containing `action` and `nonce` to perform AJAX search.
 | |
| 		 */
 | |
| 		performSearch( choicesJS, searchTerm, ajaxArgs ) {
 | |
| 			if ( ! ajaxArgs.action || ! ajaxArgs.nonce ) {
 | |
| 				return;
 | |
| 			}
 | |
| 
 | |
| 			app.displayLoading( choicesJS );
 | |
| 
 | |
| 			const requestSearchChoices = app.ajaxSearch( ajaxArgs.action, searchTerm, ajaxArgs.nonce, choicesJS.getValue( true ) );
 | |
| 
 | |
| 			requestSearchChoices.done( function( response ) {
 | |
| 				choicesJS.setChoices( response.data, 'value', 'label', true );
 | |
| 			} );
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Display "Loading" in ChoicesJS instance.
 | |
| 		 *
 | |
| 		 * @since 1.7.9
 | |
| 		 *
 | |
| 		 * @param {Choices} choicesJS ChoicesJS instance.
 | |
| 		 */
 | |
| 		displayLoading( choicesJS ) {
 | |
| 			choicesJS.setChoices(
 | |
| 				[
 | |
| 					{ value: '', label: `${ wpforms_builder.loading }...`, disabled: true },
 | |
| 				],
 | |
| 				'value',
 | |
| 				'label',
 | |
| 				true
 | |
| 			);
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Perform AJAX search request.
 | |
| 		 *
 | |
| 		 * @since 1.7.9
 | |
| 		 * @deprecated 1.9.4 Use `ajaxSearch` instead.
 | |
| 		 *
 | |
| 		 * @param {string} action     Action to be used when doing ajax request for search.
 | |
| 		 * @param {string} searchTerm Search term.
 | |
| 		 * @param {string} nonce      Nonce to be used when doing ajax request.
 | |
| 		 *
 | |
| 		 * @return {Promise} jQuery ajax call promise.
 | |
| 		 */
 | |
| 		ajaxSearchPages( action, searchTerm, nonce ) {
 | |
| 			// eslint-disable-next-line no-console
 | |
| 			console.warn( 'WPForms.Admin.Builder.WPFormsChoicesJS.ajaxSearchPages is deprecated. Use WPForms.Admin.Builder.WPFormsChoicesJS.ajaxSearch instead.' );
 | |
| 
 | |
| 			return app.ajaxSearch( action, searchTerm, nonce );
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Perform AJAX search request.
 | |
| 		 *
 | |
| 		 * @since 1.9.4
 | |
| 		 *
 | |
| 		 * @param {string} action     Action to be used when doing ajax request for search.
 | |
| 		 * @param {string} searchTerm Search term.
 | |
| 		 * @param {string} nonce      Nonce to be used when doing ajax request.
 | |
| 		 * @param {Array}  exclude    Array of values to exclude from search results.
 | |
| 		 *
 | |
| 		 * @return {Promise} jQuery ajax call promise.
 | |
| 		 */
 | |
| 		ajaxSearch( action, searchTerm, nonce, exclude = [] ) {
 | |
| 			const args = {
 | |
| 				action,
 | |
| 				search: searchTerm,
 | |
| 				_wpnonce: nonce,
 | |
| 				exclude,
 | |
| 			};
 | |
| 
 | |
| 			return $.get(
 | |
| 				wpforms_builder.ajax_url,
 | |
| 				args
 | |
| 			).fail(
 | |
| 				function( err ) {
 | |
| 					console.error( err );
 | |
| 				}
 | |
| 			);
 | |
| 		},
 | |
| 	};
 | |
| 
 | |
| 	// Provide access to public functions/properties.
 | |
| 	return app;
 | |
| 
 | |
| }( document, window, jQuery ) );
 |