PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | js/admin/style.js +67 -18 6.32.1 → trunk View file →
@@ -183,11 +183,10 @@
183 183 * @return {void}
184 184 */
185 185 function initListPage() {
186 186 document.addEventListener( 'click', handleClickEventsForListPage );
187 - // Add a timeout so Pro has a chance to add a filter first.
188 - // 0 does not always work in Google Chrome, so use 1.
189 - setTimeout( addHamburgerMenusToCards, 1 );
187 + // The dropdown options are added on the first open, so there is no longer a filter from Pro to wait for here.
188 + addHamburgerMenusToCards();
190 189 initDatepickerSample();
191 190
192 191 const enableToggle = document.getElementById( 'frm_enable_styling' );
193 192 const styleIdInput = getStyleIdInput();
@@ -722,8 +721,72 @@
722 721 hamburgerMenu.setAttribute( 'role', 'button' );
723 722 hamburgerMenu.setAttribute( 'tabindex', 0 );
724 723
725 724 const isTemplate = data.templateKey !== undefined;
725 +
726 + const dropdownMenu = div( {
727 + // Use dropdown-menu-right to avoid an overlapping issue with the card to the right (where the # of forms would appear above the menu).
728 + className: 'frm-dropdown-menu frm-style-options-menu frm-p-1'
729 + } );
730 +
731 + const isRtl = document.body.classList.contains( 'rtl' );
732 + dropdownMenu.classList.add( `dropdown-menu-${ isRtl ? 'left' : 'right' }` );
733 +
734 + dropdownMenu.setAttribute( 'role', 'menu' );
735 +
736 + fillDropdownMenuOnFirstOpen( hamburgerMenu, dropdownMenu, data, isTemplate );
737 +
738 + return div( {
739 + className: 'dropdown frm_wrap', // The .frm_wrap class prevents a blue outline on the active dropdown trigger.
740 + children: [ hamburgerMenu, dropdownMenu ]
741 + } );
742 + }
743 +
744 + /**
745 + * Add the options to a style card dropdown the first time that dropdown is opened.
746 + *
747 + * The options are built through the frm_style_card_dropdown_options filter, and Pro registers its
748 + * callback while its own script file runs. Adding the options while the page loads raced that file,
749 + * so a request for it that was slow to come back left every card holding the Lite only options.
750 + * Waiting for the first open takes the script order out of it, since Pro has always registered the
751 + * filter by the time a card can be clicked.
752 + *
753 + * @since 6.35
754 + *
755 + * @param {HTMLElement} hamburgerMenu The dropdown trigger.
756 + * @param {HTMLElement} dropdownMenu The dropdown to add the options to.
757 + * @param {DOMStringMap} data The dataset of the style card, or an object with the style ID on the edit page.
758 + * @param {boolean} isTemplate Whether the card is for a style template.
759 + * @return {void}
760 + */
761 + function fillDropdownMenuOnFirstOpen( hamburgerMenu, dropdownMenu, data, isTemplate ) {
762 + const fillDropdownMenu = () => {
763 + if ( dropdownMenu.children.length ) {
764 + return;
765 + }
766 +
767 + const options = getDropdownMenuOptions( data, isTemplate );
768 + dropdownMenu.append( ...options.map( wrapDropdownItem ) );
769 + };
770 +
771 + // Bootstrap fires this on the trigger before it measures and positions the dropdown.
772 + hamburgerMenu.addEventListener( 'show.bs.dropdown', fillDropdownMenu );
773 +
774 + // Fall back to the click in case the dropdown is ever opened without Bootstrap. Listen in the
775 + // capture phase so the options are in place before Bootstrap's own delegated handler runs.
776 + hamburgerMenu.addEventListener( 'click', fillDropdownMenu, true );
777 + }
778 +
779 + /**
780 + * Get the options for a single style card dropdown.
781 + *
782 + * @since 6.35
783 + *
784 + * @param {DOMStringMap} data The dataset of the style card, or an object with the style ID on the edit page.
785 + * @param {boolean} isTemplate Whether the card is for a style template.
786 + * @return {Array} The dropdown options, each an object with an anchor and a type.
787 + */
788 + function getDropdownMenuOptions( data, isTemplate ) {
726 789 let dropdownMenuOptions = [];
727 790
728 791 if ( isListPage ) {
729 792 const applyOption = a( {
@@ -764,23 +827,9 @@
764 827 if ( isListPage && ! isTemplate ) {
765 828 maybeAddDuplicateUpsell( dropdownMenuOptions );
766 829 }
767 830
768 - const dropdownMenu = div( {
769 - // Use dropdown-menu-right to avoid an overlapping issue with the card to the right (where the # of forms would appear above the menu).
770 - className: 'frm-dropdown-menu frm-style-options-menu frm-p-1',
771 - children: dropdownMenuOptions.map( wrapDropdownItem )
772 - } );
773 -
774 - const isRtl = document.body.classList.contains( 'rtl' );
775 - dropdownMenu.classList.add( `dropdown-menu-${ isRtl ? 'left' : 'right' }` );
776 -
777 - dropdownMenu.setAttribute( 'role', 'menu' );
778 -
779 - return div( {
780 - className: 'dropdown frm_wrap', // The .frm_wrap class prevents a blue outline on the active dropdown trigger.
781 - children: [ hamburgerMenu, dropdownMenu ]
782 - } );
831 + return dropdownMenuOptions;
783 832 }
784 833
785 834 /**
786 835 * @param {Array} dropdownMenuOptions