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
		
			
				
	
	
		
			554 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			554 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* global wpforms_builder_help, wpf */
 | |
| 
 | |
| /**
 | |
|  * WPForms Builder Help screen module.
 | |
|  *
 | |
|  * @since 1.6.3
 | |
|  */
 | |
| 
 | |
| 'use strict';
 | |
| 
 | |
| var WPForms = window.WPForms || {};
 | |
| 
 | |
| WPForms.Admin = WPForms.Admin || {};
 | |
| WPForms.Admin.Builder = WPForms.Admin.Builder || {};
 | |
| 
 | |
| WPForms.Admin.Builder.Help = WPForms.Admin.Builder.Help || ( function( document, window, $ ) {
 | |
| 
 | |
| 	/**
 | |
| 	 * Elements holder.
 | |
| 	 *
 | |
| 	 * @since 1.6.3
 | |
| 	 *
 | |
| 	 * @type {object}
 | |
| 	 */
 | |
| 	var el;
 | |
| 
 | |
| 	/**
 | |
| 	 * UI functions.
 | |
| 	 *
 | |
| 	 * @since 1.6.3
 | |
| 	 *
 | |
| 	 * @type {object}
 | |
| 	 */
 | |
| 	var ui;
 | |
| 
 | |
| 	/**
 | |
| 	 * Event handlers.
 | |
| 	 *
 | |
| 	 * @since 1.6.3
 | |
| 	 *
 | |
| 	 * @type {object}
 | |
| 	 */
 | |
| 	var event;
 | |
| 
 | |
| 	/**
 | |
| 	 * Public functions and properties.
 | |
| 	 *
 | |
| 	 * @since 1.6.3
 | |
| 	 *
 | |
| 	 * @type {object}
 | |
| 	 */
 | |
| 	var app = {
 | |
| 
 | |
| 		/**
 | |
| 		 * Start the engine. DOM is not ready yet, use only to init something.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 */
 | |
| 		init: function() {
 | |
| 
 | |
| 			$( app.ready );
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * DOM is fully loaded.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 */
 | |
| 		ready: function() {
 | |
| 
 | |
| 			app.setup();
 | |
| 			app.initCategories();
 | |
| 			app.events();
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Setup. Prepare some variables.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 */
 | |
| 		setup: function() {
 | |
| 
 | |
| 			// Cache DOM elements.
 | |
| 			el = {
 | |
| 				$builder:     $( '#wpforms-builder' ),
 | |
| 				$builderForm: $( '#wpforms-builder-form' ),
 | |
| 				$helpBtn:     $( '#wpforms-help' ),
 | |
| 				$help:        $( '#wpforms-builder-help' ),
 | |
| 				$closeBtn:    $( '#wpforms-builder-help-close' ),
 | |
| 				$search:      $( '#wpforms-builder-help-search' ),
 | |
| 				$result:      $( '#wpforms-builder-help-result' ),
 | |
| 				$noResult:    $( '#wpforms-builder-help-no-result' ),
 | |
| 				$categories:  $( '#wpforms-builder-help-categories' ),
 | |
| 				$footer:      $( '#wpforms-builder-help-footer' ),
 | |
| 			};
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Bind events.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 */
 | |
| 		events: function() {
 | |
| 
 | |
| 			// Open/close help modal.
 | |
| 			el.$helpBtn.on( 'click', event.openHelp );
 | |
| 			el.$closeBtn.on( 'click', event.closeHelp );
 | |
| 
 | |
| 			// Expand/collapse category.
 | |
| 			el.$categories.on( 'click', '.wpforms-builder-help-category header', event.toggleCategory );
 | |
| 
 | |
| 			// View all Category Docs button click.
 | |
| 			el.$categories.on( 'click', '.wpforms-builder-help-category button.viewall', event.viewAllCategoryDocs );
 | |
| 
 | |
| 			// Input into search field.
 | |
| 			el.$search.on( 'keyup', 'input', _.debounce( event.inputSearch, 250 ) );
 | |
| 
 | |
| 			// Clear search field.
 | |
| 			el.$search.on( 'click', '#wpforms-builder-help-search-clear', event.clearSearch );
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Init (generate) categories list.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 */
 | |
| 		initCategories: function() {
 | |
| 
 | |
| 			// Display error if docs data is not available.
 | |
| 			if ( wpf.empty( wpforms_builder_help.docs ) ) {
 | |
| 				el.$categories.html( wp.template( 'wpforms-builder-help-categories-error' ) );
 | |
| 
 | |
| 				return;
 | |
| 			}
 | |
| 
 | |
| 			var tmpl = wp.template( 'wpforms-builder-help-categories' ),
 | |
| 				data = {
 | |
| 					categories: wpforms_builder_help.categories,
 | |
| 					docs: app.getDocsByCategories(),
 | |
| 				};
 | |
| 
 | |
| 			el.$categories.html( tmpl( data ) );
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Init categories list.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @returns {object} Docs arranged by category.
 | |
| 		 */
 | |
| 		getDocsByCategories: function() {
 | |
| 
 | |
| 			var categories = wpforms_builder_help.categories,
 | |
| 				docs = wpforms_builder_help.docs || [],
 | |
| 				docsByCategories = {};
 | |
| 
 | |
| 			_.each( categories, function( categoryTitle, categorySlug ) {
 | |
| 				var docsByCategory = [];
 | |
| 				_.each( docs, function( doc ) {
 | |
| 					if ( doc.categories && doc.categories.indexOf( categorySlug ) > -1 ) {
 | |
| 						docsByCategory.push( doc );
 | |
| 					}
 | |
| 				} );
 | |
| 				docsByCategories[ categorySlug ] = docsByCategory;
 | |
| 			} );
 | |
| 
 | |
| 			return docsByCategories;
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Get docs recommended by search term.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @param {string} term Search term.
 | |
| 		 *
 | |
| 		 * @returns {Array} Recommended docs.
 | |
| 		 */
 | |
| 		getRecommendedDocs: function( term ) {
 | |
| 
 | |
| 			if ( wpf.empty( term ) ) {
 | |
| 				return [];
 | |
| 			}
 | |
| 
 | |
| 			term = term.toLowerCase();
 | |
| 
 | |
| 			var docs = wpforms_builder_help.docs,
 | |
| 				recommendedDocs = [];
 | |
| 
 | |
| 			if ( wpf.empty( wpforms_builder_help.context.docs[ term ] ) ) {
 | |
| 				return [];
 | |
| 			}
 | |
| 
 | |
| 			_.each( wpforms_builder_help.context.docs[ term ], function( docId ) {
 | |
| 				if ( ! wpf.empty( docs[ docId ] ) ) {
 | |
| 					recommendedDocs.push( docs[ docId ] );
 | |
| 				}
 | |
| 			} );
 | |
| 
 | |
| 			return recommendedDocs;
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Get docs filtered by search term.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @param {string} term Search term.
 | |
| 		 *
 | |
| 		 * @returns {Array} Filtered docs.
 | |
| 		 */
 | |
| 		getFilteredDocs: function( term ) {
 | |
| 
 | |
| 			if ( wpf.empty( term ) ) {
 | |
| 				return [];
 | |
| 			}
 | |
| 
 | |
| 			var docs = wpforms_builder_help.docs,
 | |
| 				filteredDocs = [];
 | |
| 
 | |
| 			term = term.toLowerCase();
 | |
| 
 | |
| 			_.each( docs, function( doc ) {
 | |
| 				if ( doc.title && doc.title.toLowerCase().indexOf( term ) > -1 ) {
 | |
| 					filteredDocs.push( doc );
 | |
| 				}
 | |
| 			} );
 | |
| 
 | |
| 			return filteredDocs;
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Get the current context (state) of the form builder.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @returns {string} Builder context string. For example 'fields/add_field' or 'settings/notifications'.
 | |
| 		 */
 | |
| 		getBuilderContext: function() {
 | |
| 
 | |
| 			// New (not saved) form.
 | |
| 			if ( wpf.empty( el.$builderForm.data( 'id' ) ) ) {
 | |
| 				return 'new_form';
 | |
| 			}
 | |
| 
 | |
| 			// Determine builder panel and section.
 | |
| 			var panel = el.$builder.find( '#wpforms-panels-toggle button.active' ).data( 'panel' ),
 | |
| 				$panel = el.$builder.find( '#wpforms-panel-' + panel ),
 | |
| 				section = '',
 | |
| 				subsection = '',
 | |
| 				context;
 | |
| 
 | |
| 			switch ( panel ) {
 | |
| 				case 'fields':
 | |
| 					section = $panel.find( '.wpforms-panel-sidebar .wpforms-tab a.active' ).parent().attr( 'id' );
 | |
| 					break;
 | |
| 				case 'setup':
 | |
| 					section = '';
 | |
| 					break;
 | |
| 				default:
 | |
| 					section = $panel.find( '.wpforms-panel-sidebar a.active' ).data( 'section' );
 | |
| 			}
 | |
| 
 | |
| 			section = ! wpf.empty( section ) ? section.replace( /-/g, '_' ) : '';
 | |
| 
 | |
| 			// Detect field type.
 | |
| 			if ( section === 'field_options' ) {
 | |
| 				subsection = $panel.find( '#wpforms-field-options .wpforms-field-option:visible .wpforms-field-option-hidden-type' ).val();
 | |
| 			}
 | |
| 
 | |
| 			// Combine to context array.
 | |
| 			context = [ panel, section, subsection ].filter( function( el ) {
 | |
| 				return ! wpf.empty( el ) && el !== 'default';
 | |
| 			} );
 | |
| 
 | |
| 			// Return imploded string.
 | |
| 			return context.join( '/' );
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Get the search term for the current builder context.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @returns {string} Builder context term string.
 | |
| 		 */
 | |
| 		getBuilderContextTerm: function() {
 | |
| 
 | |
| 			return wpforms_builder_help.context.terms[ app.getBuilderContext() ] || '';
 | |
| 		},
 | |
| 	};
 | |
| 
 | |
| 	/**
 | |
| 	 * UI functions.
 | |
| 	 */
 | |
| 	ui = {
 | |
| 
 | |
| 		/**
 | |
| 		 * Configuration.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @type {object}
 | |
| 		 */
 | |
| 		config: {
 | |
| 			speed: 300, // Fading/sliding duration in milliseconds.
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Display the element by fading them to opaque using CSS.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @param {jQuery} $el Element object.
 | |
| 		 */
 | |
| 		fadeIn: function( $el ) {
 | |
| 
 | |
| 			if ( ! $el.length ) {
 | |
| 				return;
 | |
| 			}
 | |
| 
 | |
| 			$el.css( {
 | |
| 				display: '',
 | |
| 				transition: `opacity ${ui.config.speed}ms ease-in 0s`,
 | |
| 			} );
 | |
| 
 | |
| 			setTimeout( function() {
 | |
| 				$el.css( 'opacity', '1' );
 | |
| 			}, 0 );
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Hide the element by fading them to transparent using CSS.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @param {jQuery} $el Element object.
 | |
| 		 */
 | |
| 		fadeOut: function( $el ) {
 | |
| 
 | |
| 			if ( ! $el.length ) {
 | |
| 				return;
 | |
| 			}
 | |
| 
 | |
| 			$el.css( {
 | |
| 				opacity: '0',
 | |
| 				transition: `opacity ${ui.config.speed}ms ease-in 0s`,
 | |
| 			} );
 | |
| 
 | |
| 			setTimeout( function() {
 | |
| 				$el.css( 'display', 'none' );
 | |
| 			}, ui.config.speed );
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Collapse all categories.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 */
 | |
| 		collapseAllCategories: function() {
 | |
| 
 | |
| 			el.$categories.find( '.wpforms-builder-help-category' ).removeClass( 'opened' );
 | |
| 			el.$categories.find( '.wpforms-builder-help-docs' ).slideUp();
 | |
| 		},
 | |
| 	};
 | |
| 
 | |
| 	/**
 | |
| 	 * Event handlers.
 | |
| 	 */
 | |
| 	event = {
 | |
| 
 | |
| 		/**
 | |
| 		 * Open help modal.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @param {object} e Event object.
 | |
| 		 */
 | |
| 		openHelp: function( e ) {
 | |
| 
 | |
| 			e.preventDefault();
 | |
| 
 | |
| 			$( 'body' ).addClass( 'wpforms-builder-help-open' );
 | |
| 
 | |
| 			var $firstCategory = el.$categories.find( '.wpforms-builder-help-category' ).first(),
 | |
| 				builderContextTerm = app.getBuilderContextTerm();
 | |
| 
 | |
| 			if ( builderContextTerm === '' && ! $firstCategory.hasClass( 'opened' ) ) {
 | |
| 				$firstCategory.find( 'header' ).first().trigger( 'click' );
 | |
| 			} else {
 | |
| 				ui.collapseAllCategories();
 | |
| 			}
 | |
| 
 | |
| 			el.$search.find( 'input' ).val( builderContextTerm ).trigger( 'keyup' );
 | |
| 
 | |
| 			ui.fadeIn( el.$help );
 | |
| 
 | |
| 			setTimeout( function() {
 | |
| 
 | |
| 				ui.fadeIn( el.$result );
 | |
| 				ui.fadeIn( el.$categories );
 | |
| 				ui.fadeIn( el.$footer );
 | |
| 
 | |
| 			}, ui.config.speed );
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Close help modal.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @param {object} e Event object.
 | |
| 		 */
 | |
| 		closeHelp: function( e ) {
 | |
| 
 | |
| 			e.preventDefault();
 | |
| 
 | |
| 			$( 'body' ).removeClass( 'wpforms-builder-help-open' );
 | |
| 
 | |
| 			ui.fadeOut( el.$result );
 | |
| 			ui.fadeOut( el.$categories );
 | |
| 			ui.fadeOut( el.$footer );
 | |
| 
 | |
| 			ui.fadeOut( el.$help );
 | |
| 
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Toggle category.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @param {object} e Event object.
 | |
| 		 */
 | |
| 		toggleCategory: function( e ) {
 | |
| 
 | |
| 			var $category = $( this ).parent(),
 | |
| 				$categoryDocs = $category.find( '.wpforms-builder-help-docs' );
 | |
| 
 | |
| 			if ( ! $categoryDocs.is( ':visible' ) ) {
 | |
| 				$category.addClass( 'opened' );
 | |
| 			} else {
 | |
| 				$category.removeClass( 'opened' );
 | |
| 			}
 | |
| 
 | |
| 			$categoryDocs.stop().slideToggle( ui.config.speed );
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * View All Category Docs button click.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @param {object} e Event object.
 | |
| 		 */
 | |
| 		viewAllCategoryDocs: function( e ) {
 | |
| 
 | |
| 			var $btn = $( this );
 | |
| 
 | |
| 			$btn.prev( 'div' ).stop().slideToggle( ui.config.speed, function() {
 | |
| 				$btn.closest( '.wpforms-builder-help-category' ).addClass( 'viewall' );
 | |
| 			} );
 | |
| 			ui.fadeOut( $btn );
 | |
| 			$btn.slideUp();
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Input into search field.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @param {object} e Event object.
 | |
| 		 */
 | |
| 		inputSearch: function( e ) {
 | |
| 
 | |
| 			var $input = $( this ),
 | |
| 				term = $input.val();
 | |
| 
 | |
| 			var tmpl = wp.template( 'wpforms-builder-help-docs' ),
 | |
| 				recommendedDocs = app.getRecommendedDocs( term ),
 | |
| 				filteredDocs = event.removeDuplicates( recommendedDocs, app.getFilteredDocs( term ) ),
 | |
| 				resultHTML = '';
 | |
| 
 | |
| 			el.$search.toggleClass( 'wpforms-empty', ! term );
 | |
| 
 | |
| 			if ( ! wpf.empty( recommendedDocs ) ) {
 | |
| 				resultHTML += tmpl( {
 | |
| 					docs: recommendedDocs,
 | |
| 				} );
 | |
| 			}
 | |
| 
 | |
| 			if ( ! wpf.empty( filteredDocs ) ) {
 | |
| 				resultHTML += tmpl( {
 | |
| 					docs: filteredDocs,
 | |
| 				} );
 | |
| 			}
 | |
| 
 | |
| 			el.$noResult.toggle( resultHTML === '' && term !== '' );
 | |
| 
 | |
| 			el.$result.html( resultHTML );
 | |
| 
 | |
| 			el.$help[0].scrollTop = 0;
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Remove duplicated items in the filtered docs.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @param {Array} recommendedDocs Recommended docs.
 | |
| 		 * @param {Array} filteredDocs    Filtered docs.
 | |
| 		 *
 | |
| 		 * @returns {Array} Filtered docs without duplicated items in the recommended docs.
 | |
| 		 */
 | |
| 		removeDuplicates: function( recommendedDocs, filteredDocs ) {
 | |
| 
 | |
| 			if ( wpf.empty( recommendedDocs ) || wpf.empty( filteredDocs ) ) {
 | |
| 				return filteredDocs;
 | |
| 			}
 | |
| 
 | |
| 			var docs = [];
 | |
| 
 | |
| 			for ( var i = 0; i < recommendedDocs.length, i++; ) {
 | |
| 				for ( var k = 0; k < filteredDocs.length, k++; ) {
 | |
| 					if ( filteredDocs[ k ].url !== recommendedDocs[ i ].url ) {
 | |
| 						docs.push( filteredDocs[ k ] );
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			return docs;
 | |
| 		},
 | |
| 
 | |
| 		/**
 | |
| 		 * Clear search field.
 | |
| 		 *
 | |
| 		 * @since 1.6.3
 | |
| 		 *
 | |
| 		 * @param {object} e Event object.
 | |
| 		 */
 | |
| 		clearSearch: function( e ) {
 | |
| 
 | |
| 			el.$search.find( 'input' ).val( '' ).trigger( 'keyup' );
 | |
| 		},
 | |
| 	};
 | |
| 
 | |
| 	// Provide access to public functions/properties.
 | |
| 	return app;
 | |
| 
 | |
| }( document, window, jQuery ) );
 | |
| 
 | |
| // Initialize.
 | |
| WPForms.Admin.Builder.Help.init();
 |