| @@ -44,14 +44,11 @@ | ||
| 44 | 44 | ); |
| 45 | 45 | postbox.appendChild( |
| 46 | 46 | div({ className: 'frm_modal_content' }) |
| 47 | 47 | ); |
| 48 | - | |
| 49 | - if ( footer ) { | |
| 50 | - postbox.appendChild( | |
| 51 | - div({ className: 'frm_modal_footer' }) | |
| 52 | - ); | |
| 53 | - } | |
| 48 | + postbox.appendChild( | |
| 49 | + div({ className: 'frm_modal_footer' }) | |
| 50 | + ); | |
| 54 | 51 | } else if ( 'string' === typeof title ) { |
| 55 | 52 | const titleElement = modal.querySelector( '.frm-modal-title' ); |
| 56 | 53 | titleElement.textContent = title; |
| 57 | 54 | } |
| @@ -80,21 +77,14 @@ | ||
| 80 | 77 | output.setAttribute( 'role', 'button' ); |
| 81 | 78 | output.setAttribute( 'tabindex', 0 ); |
| 82 | 79 | if ( args.buttonType ) { |
| 83 | 80 | output.classList.add( 'button' ); |
| 84 | - | |
| 85 | - if ( ! args.noDismiss && -1 !== [ 'red', 'primary' ].indexOf( args.buttonType ) ) { | |
| 86 | - // Primary and red buttons close modals by default on click. | |
| 87 | - // To disable this default behaviour you can use the noDismiss: 1 arg. | |
| 88 | - output.classList.add( 'dismiss' ); | |
| 89 | - } | |
| 90 | - | |
| 91 | 81 | switch ( args.buttonType ) { |
| 92 | - case 'red': | |
| 93 | - output.classList.add( 'frm-button-red', 'frm-button-primary' ); | |
| 94 | - break; | |
| 95 | 82 | case 'primary': |
| 96 | 83 | output.classList.add( 'button-primary', 'frm-button-primary' ); |
| 84 | + if ( ! args.noDismiss ) { | |
| 85 | + output.classList.add( 'dismiss' ); | |
| 86 | + } | |
| 97 | 87 | break; |
| 98 | 88 | case 'secondary': |
| 99 | 89 | output.classList.add( 'button-secondary', 'frm-button-secondary' ); |
| 100 | 90 | output.style.marginRight = '10px'; |
| @@ -109,13 +99,9 @@ | ||
| 109 | 99 | }; |
| 110 | 100 | |
| 111 | 101 | const ajax = { |
| 112 | 102 | doJsonFetch: async function( action ) { |
| 113 | - let targetUrl = ajaxurl + '?action=frm_' + action; | |
| 114 | - if ( -1 === targetUrl.indexOf( 'nonce=' ) ) { | |
| 115 | - targetUrl += '&nonce=' + frmGlobal.nonce; | |
| 116 | - } | |
| 117 | - const response = await fetch( targetUrl ); | |
| 103 | + const response = await fetch( ajaxurl + '?action=frm_' + action ); | |
| 118 | 104 | const json = await response.json(); |
| 119 | 105 | if ( ! json.success ) { |
| 120 | 106 | return Promise.reject( json.data || 'JSON result is not successful' ); |
| 121 | 107 | } |
| @@ -120,19 +106,16 @@ | ||
| 120 | 106 | return Promise.reject( json.data || 'JSON result is not successful' ); |
| 121 | 107 | } |
| 122 | 108 | return Promise.resolve( json.data ); |
| 123 | 109 | }, |
| 124 | - doJsonPost: async function( action, formData, { signal } = {}) { | |
| 110 | + doJsonPost: async function( action, formData ) { | |
| 125 | 111 | formData.append( 'nonce', frmGlobal.nonce ); |
| 126 | 112 | const init = { |
| 127 | 113 | method: 'POST', |
| 128 | 114 | body: formData |
| 129 | 115 | }; |
| 130 | - if ( signal ) { | |
| 131 | - init.signal = signal; | |
| 132 | - } | |
| 133 | 116 | const response = await fetch( ajaxurl + '?action=frm_' + action, init ); |
| 134 | - const json = await response.json(); | |
| 117 | + const json = await response.json(); | |
| 135 | 118 | if ( ! json.success ) { |
| 136 | 119 | return Promise.reject( json.data || 'JSON result is not successful' ); |
| 137 | 120 | } |
| 138 | 121 | return Promise.resolve( 'undefined' !== typeof json.data ? json.data : json ); |
| @@ -140,13 +123,14 @@ | ||
| 140 | 123 | }; |
| 141 | 124 | |
| 142 | 125 | const multiselect = { |
| 143 | 126 | init: function() { |
| 144 | - const $select = jQuery( this ); | |
| 145 | - const id = $select.is( '[id]' ) ? $select.attr( 'id' ).replace( '[]', '' ) : false; | |
| 127 | + let $select, id, labelledBy; | |
| 146 | 128 | |
| 147 | - let labelledBy = id ? jQuery( '#for_' + id ) : false; | |
| 148 | - labelledBy = id && labelledBy.length ? 'aria-labelledby="' + labelledBy.attr( 'id' ) + '"' : ''; | |
| 129 | + $select = jQuery( this ); | |
| 130 | + id = $select.is( '[id]' ) ? $select.attr( 'id' ).replace( '[]', '' ) : false; | |
| 131 | + labelledBy = id ? jQuery( '#for_' + id ) : false; | |
| 132 | + labelledBy = id && labelledBy.length ? 'aria-labelledby="' + labelledBy.attr( 'id' ) + '"' : ''; | |
| 149 | 133 | |
| 150 | 134 | $select.multiselect({ |
| 151 | 135 | templates: { |
| 152 | 136 | popupContainer: '<div class="multiselect-container frm-dropdown-menu"></div>', |
| @@ -163,34 +147,11 @@ | ||
| 163 | 147 | jQuery( event.currentTarget ).removeClass( 'open' ); |
| 164 | 148 | } |
| 165 | 149 | }); |
| 166 | 150 | } |
| 167 | - | |
| 168 | - const $dropdown = $select.next( '.frm-btn-group.dropdown' ); | |
| 169 | - $dropdown.find( '.dropdown-item' ).each( | |
| 170 | - function() { | |
| 171 | - const option = this; | |
| 172 | - const dropdownInput = option.querySelector( 'input[type="checkbox"], input[type="radio"]' ); | |
| 173 | - if ( dropdownInput ) { | |
| 174 | - option.setAttribute( 'role', 'checkbox' ); | |
| 175 | - option.setAttribute( 'aria-checked', dropdownInput.checked ? 'true' : 'false' ); | |
| 176 | - } | |
| 177 | - } | |
| 178 | - ); | |
| 179 | 151 | }, |
| 180 | - onChange: function( $option, checked ) { | |
| 181 | - $select.trigger( 'frm-multiselect-changed', $option, checked ); | |
| 182 | - | |
| 183 | - const $dropdown = $select.next( '.frm-btn-group.dropdown' ); | |
| 184 | - const optionValue = $option.val(); | |
| 185 | - const $dropdownItem = $dropdown.find( 'input[value="' + optionValue + '"]' ).closest( 'button.dropdown-item' ); | |
| 186 | - if ( $dropdownItem.length ) { | |
| 187 | - $dropdownItem.attr( 'aria-checked', checked ? 'true' : 'false' ); | |
| 188 | - | |
| 189 | - // Delay a focus event so the screen reader reads the option value again. | |
| 190 | - // Without this, and without the setTimeout, it only reads "checked" or "unchecked". | |
| 191 | - setTimeout( () => $dropdownItem.get( 0 ).focus(), 0 ); | |
| 192 | - } | |
| 152 | + onChange: function( element, option ) { | |
| 153 | + $select.trigger( 'frm-multiselect-changed', element, option ); | |
| 193 | 154 | } |
| 194 | 155 | }); |
| 195 | 156 | } |
| 196 | 157 | }; |
| @@ -355,9 +316,9 @@ | ||
| 355 | 316 | const wrappedSearch = search.wrapInput( input, placeholder ); |
| 356 | 317 | search.init( input, targetClassName, args ); |
| 357 | 318 | |
| 358 | 319 | function getAutoSearchInput( id, placeholder ) { |
| 359 | - const className = 'frm-search-input frm-auto-search frm-w-full'; | |
| 320 | + const className = 'frm-search-input frm-auto-search'; | |
| 360 | 321 | const inputArgs = { id, className }; |
| 361 | 322 | const input = tag( 'input', inputArgs ); |
| 362 | 323 | input.setAttribute( 'placeholder', placeholder ); |
| 363 | 324 | return input; |
| @@ -423,41 +384,13 @@ | ||
| 423 | 384 | event.preventDefault(); |
| 424 | 385 | callback( event ); |
| 425 | 386 | }; |
| 426 | 387 | element.addEventListener( 'click', listener ); |
| 427 | - }, | |
| 428 | - | |
| 429 | - /** | |
| 430 | - * Does the same as jQuery( document ).on( 'event', 'selector', handler ). | |
| 431 | - * | |
| 432 | - * @since 6.0 | |
| 433 | - * | |
| 434 | - * @param {String} event Event name. | |
| 435 | - * @param {String} selector Selector. | |
| 436 | - * @param {Function} handler Handler. | |
| 437 | - * @param {Boolean|Object} options Options to be added to `addEventListener()` method. Default is `false`. | |
| 438 | - */ | |
| 439 | - documentOn: ( event, selector, handler, options ) => { | |
| 440 | - if ( 'undefined' === typeof options ) { | |
| 441 | - options = false; | |
| 442 | - } | |
| 443 | - | |
| 444 | - document.addEventListener( event, function( e ) { | |
| 445 | - let target; | |
| 446 | - | |
| 447 | - // loop parent nodes from the target to the delegation node. | |
| 448 | - for ( target = e.target; target && target != this; target = target.parentNode ) { | |
| 449 | - if ( target && target.matches && target.matches( selector ) ) { | |
| 450 | - handler.call( target, e ); | |
| 451 | - break; | |
| 452 | - } | |
| 453 | - } | |
| 454 | - }, options ); | |
| 455 | 388 | } |
| 456 | 389 | }; |
| 457 | 390 | |
| 458 | 391 | const wysiwyg = { |
| 459 | - init( editor, { setupCallback, height, addFocusEvents } = {}) { | |
| 392 | + init( editor, { setupCallback } = {}) { | |
| 460 | 393 | if ( isTinyMceActive() ) { |
| 461 | 394 | setTimeout( resetTinyMce, 0 ); |
| 462 | 395 | } else { |
| 463 | 396 | initQuickTagsButtons(); |
| @@ -494,28 +427,10 @@ | ||
| 494 | 427 | body_class: orgSettings.body_class.replace( key, editor.id ) |
| 495 | 428 | } |
| 496 | 429 | ); |
| 497 | 430 | |
| 498 | - settings.setup = editor => { | |
| 499 | - if ( addFocusEvents ) { | |
| 500 | - function focusInCallback() { | |
| 501 | - jQuery( editor.targetElm ).trigger( 'focusin' ); | |
| 502 | - editor.off( 'focusin', '**' ); | |
| 503 | - } | |
| 504 | - | |
| 505 | - editor.on( 'focusin', focusInCallback ); | |
| 506 | - | |
| 507 | - editor.on( 'focusout', function() { | |
| 508 | - editor.on( 'focusin', focusInCallback ); | |
| 509 | - }); | |
| 510 | - } | |
| 511 | - if ( setupCallback ) { | |
| 512 | - setupCallback( editor ); | |
| 513 | - } | |
| 514 | - }; | |
| 515 | - | |
| 516 | - if ( height ) { | |
| 517 | - settings.height = height; | |
| 431 | + if ( setupCallback ) { | |
| 432 | + settings.setup = setupCallback; | |
| 518 | 433 | } |
| 519 | 434 | |
| 520 | 435 | tinymce.init( settings ); |
| 521 | 436 | } |
| @@ -587,10 +502,8 @@ | ||
| 587 | 502 | return modal; |
| 588 | 503 | } |
| 589 | 504 | |
| 590 | 505 | function makeModalIntoADialogAndOpen( modal, { width } = {}) { |
| 591 | - const bodyWithModalClassName = 'frm-body-with-open-modal'; | |
| 592 | - | |
| 593 | 506 | const $modal = jQuery( modal ); |
| 594 | 507 | if ( ! $modal.hasClass( 'frm-dialog' ) ) { |
| 595 | 508 | $modal.dialog({ |
| 596 | 509 | dialogClass: 'frm-dialog', |
| @@ -623,9 +536,9 @@ | ||
| 623 | 536 | ); |
| 624 | 537 | } |
| 625 | 538 | }, |
| 626 | 539 | close: function() { |
| 627 | - document.body.classList.remove( bodyWithModalClassName ); | |
| 540 | + document.body.style.overflowY = 'initial'; | |
| 628 | 541 | jQuery( '#wpwrap' ).removeClass( 'frm_overlay' ); |
| 629 | 542 | jQuery( '.spinner' ).css( 'visibility', 'hidden' ); |
| 630 | 543 | } |
| 631 | 544 | }); |
| @@ -630,10 +543,9 @@ | ||
| 630 | 543 | } |
| 631 | 544 | }); |
| 632 | 545 | } |
| 633 | 546 | |
| 634 | - document.body.classList.add( bodyWithModalClassName ); | |
| 635 | - | |
| 547 | + document.body.style.overflowY = 'hidden'; | |
| 636 | 548 | $modal.dialog( 'open' ); |
| 637 | 549 | return $modal; |
| 638 | 550 | } |
| 639 | 551 | |
| @@ -658,50 +570,11 @@ | ||
| 658 | 570 | const output = tag( 'img', args ); |
| 659 | 571 | if ( 'string' === typeof args.src ) { |
| 660 | 572 | output.setAttribute( 'src', args.src ); |
| 661 | 573 | } |
| 662 | - if ( 'string' === typeof args.alt ) { | |
| 663 | - output.setAttribute( 'alt', args.alt ); | |
| 664 | - } | |
| 665 | 574 | return output; |
| 666 | 575 | } |
| 667 | 576 | |
| 668 | - /** | |
| 669 | - * Get a labelled text input and a matching label. | |
| 670 | - * | |
| 671 | - * @since 6.0 | |
| 672 | - * | |
| 673 | - * @param {String} inputId | |
| 674 | - * @param {String} labelText | |
| 675 | - * @param {String} inputName | |
| 676 | - * @returns {Element} | |
| 677 | - */ | |
| 678 | - function labelledTextInput( inputId, labelText, inputName ) { | |
| 679 | - const label = tag( 'label', labelText ); | |
| 680 | - label.setAttribute( 'for', inputId ); | |
| 681 | - | |
| 682 | - const input = tag( | |
| 683 | - 'input', | |
| 684 | - { | |
| 685 | - id: inputId, | |
| 686 | - className: 'frm_long_input' | |
| 687 | - } | |
| 688 | - ); | |
| 689 | - input.type = 'text'; | |
| 690 | - input.setAttribute( 'name', inputName ); | |
| 691 | - | |
| 692 | - return div({ children: [ label, input ] }); | |
| 693 | - } | |
| 694 | - | |
| 695 | - /** | |
| 696 | - * Build an element. | |
| 697 | - * | |
| 698 | - * @since 6.4.1 Accept a string as one of `children` to append a text node inside the element. | |
| 699 | - * | |
| 700 | - * @param {String} type Element tag name. | |
| 701 | - * @param {Object} args The args. | |
| 702 | - * @return {Object} | |
| 703 | - */ | |
| 704 | 577 | function tag( type, args = {}) { |
| 705 | 578 | const output = document.createElement( type ); |
| 706 | 579 | |
| 707 | 580 | if ( 'string' === typeof args ) { |
| @@ -709,9 +582,9 @@ | ||
| 709 | 582 | output.textContent = args; |
| 710 | 583 | return output; |
| 711 | 584 | } |
| 712 | 585 | |
| 713 | - const { id, className, children, child, text, data } = args; | |
| 586 | + const { id, className, children, child, text } = args; | |
| 714 | 587 | |
| 715 | 588 | if ( id ) { |
| 716 | 589 | output.id = id; |
| 717 | 590 | } |
| @@ -718,25 +591,14 @@ | ||
| 718 | 591 | if ( className ) { |
| 719 | 592 | output.className = className; |
| 720 | 593 | } |
| 721 | 594 | if ( children ) { |
| 722 | - children.forEach( child => { | |
| 723 | - if ( 'string' === typeof child ) { | |
| 724 | - output.appendChild( document.createTextNode( child ) ); | |
| 725 | - } else { | |
| 726 | - output.appendChild( child ) | |
| 727 | - } | |
| 728 | - } ); | |
| 595 | + children.forEach( child => output.appendChild( child ) ); | |
| 729 | 596 | } else if ( child ) { |
| 730 | 597 | output.appendChild( child ); |
| 731 | 598 | } else if ( text ) { |
| 732 | 599 | output.textContent = text; |
| 733 | 600 | } |
| 734 | - if ( data ) { | |
| 735 | - Object.keys( data ).forEach( function( dataKey ) { | |
| 736 | - output.setAttribute( 'data-' + dataKey, data[dataKey] ); | |
| 737 | - }); | |
| 738 | - } | |
| 739 | 601 | return output; |
| 740 | 602 | } |
| 741 | 603 | |
| 742 | 604 | function svg({ href, classList } = {}) { |
| @@ -754,32 +616,8 @@ | ||
| 754 | 616 | } |
| 755 | 617 | return output; |
| 756 | 618 | } |
| 757 | 619 | |
| 758 | - /** | |
| 759 | - * Pop up a success message in the lower right corner. | |
| 760 | - * It then fades out and gets deleted automatically. | |
| 761 | - * | |
| 762 | - * @param {HTMLElement|String} content | |
| 763 | - * @returns {void} | |
| 764 | - */ | |
| 765 | - function success( content ) { | |
| 766 | - const container = document.getElementById( 'wpbody' ); | |
| 767 | - const notice = div({ | |
| 768 | - className: 'notice notice-info frm-review-notice frm_updated_message frm-floating-success-message', | |
| 769 | - child: div({ | |
| 770 | - className: 'frm-satisfied', | |
| 771 | - child: 'string' === typeof content ? document.createTextNode( content ) : content | |
| 772 | - }) | |
| 773 | - }); | |
| 774 | - container.appendChild( notice ); | |
| 775 | - | |
| 776 | - setTimeout( | |
| 777 | - () => jQuery( notice ).fadeOut( () => notice.remove() ), | |
| 778 | - 2000 | |
| 779 | - ); | |
| 780 | - } | |
| 781 | - | |
| 782 | 620 | function setAttributes( element, attrs ) { |
| 783 | 621 | Object.entries( attrs ).forEach( |
| 784 | 622 | ([ key, value ]) => element.setAttribute( key, value ) |
| 785 | 623 | ); |
| @@ -789,53 +627,6 @@ | ||
| 789 | 627 | element.innerHTML = ''; |
| 790 | 628 | element.appendChild( child ); |
| 791 | 629 | } |
| 792 | 630 | |
| 793 | - const allowedHtml = { | |
| 794 | - b: [], | |
| 795 | - div: [ 'class' ], | |
| 796 | - img: [ 'src', 'alt' ], | |
| 797 | - p: [], | |
| 798 | - span: [ 'class' ], | |
| 799 | - strong: [], | |
| 800 | - svg: [ 'class' ], | |
| 801 | - use: [] | |
| 802 | - }; | |
| 803 | - | |
| 804 | - function cleanNode( node ) { | |
| 805 | - if ( 'undefined' === typeof node.tagName ) { | |
| 806 | - if ( '#text' === node.nodeName ) { | |
| 807 | - return document.createTextNode( node.textContent ); | |
| 808 | - } | |
| 809 | - return document.createTextNode( '' ); | |
| 810 | - } | |
| 811 | - | |
| 812 | - const tagType = node.tagName.toLowerCase(); | |
| 813 | - | |
| 814 | - if ( 'svg' === tagType ) { | |
| 815 | - return svg({ | |
| 816 | - href: node.querySelector( 'use' ).getAttribute( 'xlink:href' ), | |
| 817 | - classList: Array.from( node.classList ) | |
| 818 | - }); | |
| 819 | - } | |
| 820 | - | |
| 821 | - const newNode = document.createElement( tagType ); | |
| 822 | - | |
| 823 | - if ( 'undefined' === typeof allowedHtml[ tagType ]) { | |
| 824 | - // Tag type is not allowed. | |
| 825 | - return document.createTextNode( '' ); | |
| 826 | - } | |
| 827 | - | |
| 828 | - allowedHtml[ tagType ].forEach( | |
| 829 | - allowedTag => { | |
| 830 | - if ( node.hasAttribute( allowedTag ) ) { | |
| 831 | - newNode.setAttribute( allowedTag, node.getAttribute( allowedTag ) ); | |
| 832 | - } | |
| 833 | - } | |
| 834 | - ); | |
| 835 | - | |
| 836 | - node.childNodes.forEach( child => newNode.appendChild( cleanNode( child ) ) ); | |
| 837 | - return newNode; | |
| 838 | - } | |
| 839 | - | |
| 840 | - window.frmDom = { tag, div, span, a, img, labelledTextInput, svg, setAttributes, success, modal, ajax, bootstrap, autocomplete, search, util, wysiwyg, cleanNode }; | |
| 631 | + window.frmDom = { tag, div, span, a, img, svg, setAttributes, modal, ajax, bootstrap, autocomplete, search, util, wysiwyg }; | |
| 841 | 632 | }() ); |