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/dom.js +52 -54 6.27 → trunk View file →
@@ -2,9 +2,9 @@
2 2 /** globals frmGlobal */
3 3
4 4 let __;
5 5
6 - if ( 'undefined' === typeof wp || 'undefined' === typeof wp.i18n || 'function' !== typeof wp.i18n.__ ) {
6 + if ( 'undefined' === typeof wp || wp.i18n === undefined || 'function' !== typeof wp.i18n.__ ) {
7 7 __ = text => text;
8 8 } else {
9 9 __ = wp.i18n.__;
10 10 }
@@ -81,9 +81,9 @@
81 81 output.setAttribute( 'tabindex', 0 );
82 82 if ( args.buttonType ) {
83 83 output.classList.add( 'button' );
84 84
85 - if ( ! args.noDismiss && -1 !== [ 'red', 'primary' ].indexOf( args.buttonType ) ) {
85 + if ( ! args.noDismiss && [ 'red', 'primary' ].includes( args.buttonType ) ) {
86 86 // Primary and red buttons close modals by default on click.
87 87 // To disable this default behaviour you can use the noDismiss: 1 arg.
88 88 output.classList.add( 'dismiss' );
89 89 }
@@ -108,12 +108,12 @@
108 108 }
109 109 };
110 110
111 111 const ajax = {
112 - doJsonFetch: async function( action ) {
113 - let targetUrl = ajaxurl + '?action=frm_' + action;
114 - if ( -1 === targetUrl.indexOf( 'nonce=' ) ) {
115 - targetUrl += '&nonce=' + frmGlobal.nonce;
112 + async doJsonFetch( action ) {
113 + let targetUrl = `${ ajaxurl }?action=frm_${ action }`;
114 + if ( ! targetUrl.includes( 'nonce=' ) ) {
115 + targetUrl += `&nonce=${ frmGlobal.nonce }`;
116 116 }
117 117 const response = await fetch( targetUrl );
118 118 const json = await response.json();
119 119 if ( ! json.success ) {
@@ -120,9 +120,9 @@
120 120 return Promise.reject( json.data || 'JSON result is not successful' );
121 121 }
122 122 return Promise.resolve( json.data );
123 123 },
124 - doJsonPost: async function( action, formData, { signal } = {} ) {
124 + async doJsonPost( action, formData, { signal } = {} ) {
125 125 formData.append( 'nonce', frmGlobal.nonce );
126 126 const init = {
127 127 method: 'POST',
128 128 body: formData
@@ -129,32 +129,30 @@
129 129 };
130 130 if ( signal ) {
131 131 init.signal = signal;
132 132 }
133 - const response = await fetch( ajaxurl + '?action=frm_' + action, init );
133 + const response = await fetch( `${ ajaxurl }?action=frm_${ action }`, init );
134 134 const json = await response.json();
135 135 if ( ! json.success ) {
136 136 return Promise.reject( json.data || 'JSON result is not successful' );
137 137 }
138 - return Promise.resolve( 'undefined' !== typeof json.data ? json.data : json );
138 + return Promise.resolve( json.data !== undefined ? json.data : json );
139 139 }
140 140 };
141 141
142 142 const multiselect = {
143 - init: function() {
143 + init() {
144 144 const $select = jQuery( this );
145 145 const id = $select.is( '[id]' ) ? $select.attr( 'id' ).replace( '[]', '' ) : false;
146 146
147 - let labelledBy = id ? jQuery( '#for_' + id ) : false;
148 - labelledBy = id && labelledBy.length ? 'aria-labelledby="' + labelledBy.attr( 'id' ) + '"' : '';
147 + let labelledBy = id ? jQuery( `#for_${ id }` ) : false;
148 + labelledBy = id && labelledBy.length ? `aria-labelledby="${ labelledBy.attr( 'id' ) }"` : '';
149 149
150 - // Set empty title attributes so that none of the dropdown options include title attributes.
151 - $select.find( 'option' ).attr( 'title', ' ' );
152 150 $select.multiselect( {
153 151 templates: {
154 152 popupContainer: '<div class="multiselect-container frm-dropdown-menu dropdown-menu"></div>',
155 153 option: '<button type="button" class="multiselect-option dropdown-item frm_no_style_button"></button>',
156 - button: '<button type="button" class="multiselect dropdown-toggle btn" data-bs-toggle="dropdown" ' + labelledBy + '><span class="multiselect-selected-text"></span> <b class="caret"></b></button>'
154 + button: `<button type="button" class="multiselect dropdown-toggle btn" data-bs-toggle="dropdown" ${ labelledBy }><span class="multiselect-selected-text"></span> <b class="caret"></b></button>`
157 155 },
158 156 buttonContainer: '<div class="btn-group frm-btn-group dropdown" />',
159 157 nonSelectedText: __( '— Select —', 'formidable' ),
160 158 // Prevent the dropdown from showing "All Selected" when every option is checked.
@@ -160,12 +158,12 @@
160 158 // Prevent the dropdown from showing "All Selected" when every option is checked.
161 159 allSelectedText: '',
162 160 // This is 3 by default. We want to show more options before it starts showing a count.
163 161 numberDisplayed: 8,
164 - onInitialized: function( _, $container ) {
165 - $container.find( '.multiselect.dropdown-toggle' ).removeAttr( 'title' );
162 + onInitialized( _, $container ) {
163 + $container.find( '.multiselect.dropdown-toggle,.multiselect-option.dropdown-item' ).removeAttr( 'title' );
166 164 },
167 - onDropdownShown: function( event ) {
165 + onDropdownShown( event ) {
168 166 const action = jQuery( event.currentTarget.closest( '.frm_form_action_settings, #frm-show-fields' ) );
169 167 if ( action.length ) {
170 168 jQuery( '#wpcontent' ).on( 'click', function() {
171 169 if ( jQuery( '.multiselect-container.frm-dropdown-menu' ).is( ':visible' ) ) {
@@ -185,14 +183,14 @@
185 183 }
186 184 }
187 185 );
188 186 },
189 - onChange: function( $option, checked ) {
187 + onChange( $option, checked ) {
190 188 $select.trigger( 'frm-multiselect-changed', $option, checked );
191 189
192 190 const $dropdown = $select.next( '.frm-btn-group.dropdown' );
193 191 const optionValue = $option.val();
194 - const $dropdownItem = $dropdown.find( 'input[value="' + optionValue + '"]' ).closest( 'button.dropdown-item' );
192 + const $dropdownItem = $dropdown.find( `input[value="${ optionValue }"]` ).closest( 'button.dropdown-item' );
195 193 if ( $dropdownItem.length ) {
196 194 $dropdownItem.attr( 'aria-checked', checked ? 'true' : 'false' );
197 195
198 196 // Delay a focus event so the screen reader reads the option value again.
@@ -204,9 +202,9 @@
204 202 }
205 203 };
206 204
207 205 const bootstrap = {
208 - setupBootstrapDropdowns: function() {
206 + setupBootstrapDropdowns() {
209 207 // This function is no longer necessary.
210 208 // It's call in Pro though, so keep it to avoid any errors for now.
211 209 },
212 210 multiselect
@@ -212,9 +210,9 @@
212 210 multiselect
213 211 };
214 212
215 213 const autocomplete = {
216 - initSelectionAutocomplete: function( container ) {
214 + initSelectionAutocomplete( container ) {
217 215 if ( jQuery.fn.autocomplete ) {
218 216 autocomplete.initAutocomplete( 'page', container );
219 217 autocomplete.initAutocomplete( 'user', container );
220 218 autocomplete.initAutocomplete( 'custom', container );
@@ -227,11 +225,11 @@
227 225 *
228 226 * @param {string} type Type of data. Accepts `page` or `user`.
229 227 * @param {string|Object} container Container class or element. Default is null.
230 228 */
231 - initAutocomplete: function( type, container ) {
232 - const basedUrlParams = '?action=frm_' + type + '_search&nonce=' + frmGlobal.nonce;
233 - const elements = ! container ? jQuery( '.frm-' + type + '-search' ) : jQuery( container ).find( '.frm-' + type + '-search' );
229 + initAutocomplete( type, container ) {
230 + const basedUrlParams = `?action=frm_${ type }_search&nonce=${ frmGlobal.nonce }`;
231 + const elements = ! container ? jQuery( `.frm-${ type }-search` ) : jQuery( container ).find( `.frm-${ type }-search` );
234 232
235 233 elements.each( initAutocompleteForElement );
236 234
237 235 function initAutocompleteForElement() {
@@ -239,9 +237,9 @@
239 237 const element = jQuery( this );
240 238
241 239 // Check if a custom post type is specific.
242 240 if ( element.attr( 'data-post-type' ) ) {
243 - urlParams += '&post_type=' + element.attr( 'data-post-type' );
241 + urlParams += `&post_type=${ element.attr( 'data-post-type' ) }`;
244 242 }
245 243
246 244 let source = ajaxurl + urlParams;
247 245
@@ -254,9 +252,9 @@
254 252
255 253 element.autocomplete( {
256 254 delay: 100,
257 255 minLength: 0,
258 - source: source,
256 + source,
259 257 change: autocomplete.selectBlank,
260 258 select: autocomplete.completeSelectFromResults,
261 259 focus: () => false,
262 260 position: {
@@ -263,9 +261,9 @@
263 261 my: 'left top',
264 262 at: 'left bottom',
265 263 collision: 'flip'
266 264 },
267 - response: function( event, ui ) {
265 + response( event, ui ) {
268 266 if ( ! ui.content.length ) {
269 267 const noResult = {
270 268 value: '',
271 269 label: frm_admin_js.no_items_found
@@ -272,9 +270,9 @@
272 270 };
273 271 ui.content.push( noResult );
274 272 }
275 273 },
276 - create: function() {
274 + create() {
277 275 let $container = jQuery( this ).parent();
278 276
279 277 if ( $container.length === 0 ) {
280 278 $container = 'body';
@@ -297,9 +295,9 @@
297 295 };
298 296 }
299 297 },
300 298
301 - selectBlank: function( e, ui ) {
299 + selectBlank( e, ui ) {
302 300 if ( ui.item === null ) {
303 301 this.nextElementSibling.value = '';
304 302
305 303 /**
@@ -310,9 +308,9 @@
310 308 wp.hooks.doAction( 'frm_autocomplete_clear_value', e, ui, this );
311 309 }
312 310 },
313 311
314 - completeSelectFromResults: function( e, ui ) {
312 + completeSelectFromResults( e, ui ) {
315 313 e.preventDefault();
316 314 this.value = ui.item.value === '' ? '' : ui.item.label;
317 315 this.nextElementSibling.value = ui.item.value;
318 316
@@ -390,9 +388,9 @@
390 388 itemText = item.innerText.toLowerCase();
391 389 item.setAttribute( 'frm-search-text', itemText );
392 390 }
393 391
394 - const hide = notEmptySearchText && -1 === itemText.indexOf( searchText );
392 + const hide = notEmptySearchText && ! itemText.includes( searchText );
395 393 item.classList.toggle( 'frm_hidden', hide );
396 394
397 395 const isSearchResult = ! hide && notEmptySearchText;
398 396 if ( isSearchResult ) {
@@ -433,9 +431,9 @@
433 431 * @param {Function} handler Handler.
434 432 * @param {boolean|Object} options Options to be added to `addEventListener()` method. Default is `false`.
435 433 */
436 434 documentOn: ( event, selector, handler, options ) => {
437 - if ( 'undefined' === typeof options ) {
435 + if ( options === undefined ) {
438 436 options = false;
439 437 }
440 438
441 439 document.addEventListener( event, function( e ) {
@@ -442,9 +440,9 @@
442 440 let target;
443 441
444 442 // loop parent nodes from the target to the delegation node.
445 443 for ( target = e.target; target && target != this; target = target.parentNode ) {
446 - if ( target && target.matches && target.matches( selector ) ) {
444 + if ( target.matches && target.matches( selector ) ) {
447 445 handler.call( target, e );
448 446 break;
449 447 }
450 448 }
@@ -491,19 +489,19 @@
491 489 setUpTinyMceVisualButtonListener();
492 490 setUpTinyMceHtmlButtonListener();
493 491
494 492 function initQuickTagsButtons() {
495 - if ( 'function' !== typeof window.quicktags || typeof window.QTags.instances[ editor.id ] !== 'undefined' ) {
493 + if ( 'function' !== typeof window.quicktags || window.QTags.instances[ editor.id ] !== undefined ) {
496 494 return;
497 495 }
498 496
499 - const id = editor.id;
497 + const { id } = editor;
500 498 window.quicktags( {
501 - name: 'qt_' + id,
502 - id: id,
499 + name: `qt_${ id }`,
500 + id,
503 501 canvas: editor,
504 502 settings: { id },
505 - toolbar: document.getElementById( 'qt_' + id + '_toolbar' ),
503 + toolbar: document.getElementById( `qt_${ id }_toolbar` ),
506 504 theButtons: {}
507 505 } );
508 506 }
509 507
@@ -514,9 +512,9 @@
514 512 const settings = Object.assign(
515 513 {},
516 514 orgSettings,
517 515 {
518 - selector: '#' + editor.id,
516 + selector: `#${ editor.id }`,
519 517 body_class: orgSettings.body_class.replace( key, editor.id )
520 518 }
521 519 );
522 520
@@ -554,16 +552,16 @@
554 552 initRichText();
555 553 }
556 554
557 555 function isTinyMceActive() {
558 - const id = editor.id;
559 - const wrapper = document.getElementById( 'wp-' + id + '-wrap' );
560 - return null !== wrapper && wrapper.classList.contains( 'tmce-active' );
556 + const { id } = editor;
557 + const wrapper = document.getElementById( `wp-${ id }-wrap` );
558 + return wrapper && wrapper.classList.contains( 'tmce-active' );
561 559 }
562 560
563 561 function setUpTinyMceVisualButtonListener() {
564 562 jQuery( document ).on(
565 - 'click', '#' + editor.id + '-html',
563 + 'click', `#${ editor.id }-html`,
566 564 function() {
567 565 editor.style.visibility = 'visible';
568 566 initQuickTagsButtons();
569 567 }
@@ -570,9 +568,9 @@
570 568 );
571 569 }
572 570
573 571 function setUpTinyMceHtmlButtonListener() {
574 - jQuery( '#' + editor.id + '-tmce' ).on( 'click', handleTinyMceHtmlButtonClick );
572 + jQuery( `#${ editor.id }-tmce` ).on( 'click', handleTinyMceHtmlButtonClick );
575 573 }
576 574
577 575 function handleTinyMceHtmlButtonClick() {
578 576 if ( isTinyMceActive() ) {
@@ -580,9 +578,9 @@
580 578 } else {
581 579 initRichText();
582 580 }
583 581
584 - const wrap = document.getElementById( 'wp-' + editor.id + '-wrap' );
582 + const wrap = document.getElementById( `wp-${ editor.id }-wrap` );
585 583 wrap.classList.add( 'tmce-active' );
586 584 wrap.classList.remove( 'html-active' );
587 585 }
588 586 }
@@ -589,12 +587,12 @@
589 587 };
590 588
591 589 function getModalHelper( modal, appendTo ) {
592 590 return function( child, uniqueClassName ) {
593 - let element = modal.querySelector( '.' + uniqueClassName );
591 + let element = modal.querySelector( `.${ uniqueClassName }` );
594 592 if ( null === element ) {
595 593 element = div( {
596 - child: child,
594 + child,
597 595 className: uniqueClassName
598 596 } );
599 597 appendTo.append( element );
600 598 } else {
@@ -617,9 +615,9 @@
617 615
618 616 const $modal = jQuery( modal );
619 617 if ( ! $modal.hasClass( 'frm-dialog' ) ) {
620 618 $modal.dialog( {
621 - dialogClass: 'frm-dialog ' + dialogClass,
619 + dialogClass: `frm-dialog ${ dialogClass }`,
622 620 modal: true,
623 621 autoOpen: false,
624 622 closeOnEscape: true,
625 623 width: width || '550px',
@@ -624,9 +622,9 @@
624 622 closeOnEscape: true,
625 623 width: width || '550px',
626 624 resizable: false,
627 625 draggable: false,
628 - open: function() {
626 + open() {
629 627 jQuery( '.ui-dialog-titlebar' ).addClass( 'frm_hidden' ).removeClass( 'ui-helper-clearfix' );
630 628 jQuery( '#wpwrap' ).addClass( 'frm_overlay' );
631 629 jQuery( '.frm-dialog' ).removeClass( 'ui-widget ui-widget-content ui-corner-all' );
632 630
@@ -647,9 +645,9 @@
647 645 }
648 646 );
649 647 }
650 648 },
651 - close: function() {
649 + close() {
652 650 document.body.classList.remove( bodyWithModalClassName );
653 651 jQuery( '#wpwrap' ).removeClass( 'frm_overlay' );
654 652 jQuery( '.spinner' ).css( 'visibility', 'hidden' );
655 653 }
@@ -757,9 +755,9 @@
757 755 output.textContent = text;
758 756 }
759 757 if ( data ) {
760 758 Object.keys( data ).forEach( function( dataKey ) {
761 - output.setAttribute( 'data-' + dataKey, data[ dataKey ] );
759 + output.setAttribute( `data-${ dataKey }`, data[ dataKey ] );
762 760 } );
763 761 }
764 762 return output;
765 763 }
@@ -827,9 +825,9 @@
827 825 a: [ 'href', 'class' ]
828 826 };
829 827
830 828 function cleanNode( node ) {
831 - if ( 'undefined' === typeof node.tagName ) {
829 + if ( node.tagName === undefined ) {
832 830 if ( '#text' === node.nodeName ) {
833 831 return document.createTextNode( node.textContent );
834 832 }
835 833 return document.createTextNode( '' );
@@ -847,9 +845,9 @@
847 845 }
848 846 return svg( svgArgs );
849 847 }
850 848
851 - if ( 'undefined' === typeof allowedHtml[ tagType ] ) {
849 + if ( allowedHtml[ tagType ] === undefined ) {
852 850 // Tag type is not allowed.
853 851 return document.createTextNode( '' );
854 852 }
855 853