1/** 2 * Contact Block - Age Verification 3 * 4 * Verifies users are 13+ before revealing the contact form iframe. 5 * 6 * @package StudioSwift 7 */ 8 9(function() { 10 'use strict'; 11 12 var MIN_AGE = 13; 13 14 /** 15 * Calculate age from a birth date. 16 * 17 * @param {number} year Birth year. 18 * @param {number} month Birth month (1-12). 19 * @param {number} day Birth day. 20 * @return {number|null} Age in years, or null if the date is invalid. 21 */ 22 function calculateAge( year, month, day ) { 23 var birthDate = new Date( year, month - 1, day ); 24 25 if ( 26 birthDate.getFullYear() !== year || 27 birthDate.getMonth() !== month - 1 || 28 birthDate.getDate() !== day 29 ) { 30 return null; 31 } 32 33 var today = new Date(); 34 var age = today.getFullYear() - birthDate.getFullYear(); 35 var monthDiff = today.getMonth() - birthDate.getMonth(); 36 37 if ( monthDiff < 0 || ( monthDiff === 0 && today.getDate() < birthDate.getDate() ) ) { 38 age--; 39 } 40 41 return age; 42 } 43 44 /** 45 * Show or hide a panel using hidden attribute and aria-hidden. 46 * 47 * @param {HTMLElement} element Target element. 48 * @param {boolean} show Whether the element should be visible. 49 */ 50 function togglePanel( element, show ) { 51 if ( ! element ) { 52 return; 53 } 54 55 element.hidden = ! show; 56 element.setAttribute( 'aria-hidden', show ? 'false' : 'true' ); 57 element.classList.toggle( 'is-hidden', ! show ); 58 } 59 60 /** 61 * Initialize age verification for a single contact form instance. 62 * 63 * @param {HTMLElement} formWrapper Contact form wrapper element. 64 */ 65 function initAgeVerification( formWrapper ) { 66 if ( formWrapper.dataset.ageVerificationInitialized === 'true' ) { 67 return; 68 } 69 70 var monthSelect = formWrapper.querySelector( '[data-dob-month]' ); 71 var daySelect = formWrapper.querySelector( '[data-dob-day]' ); 72 var yearSelect = formWrapper.querySelector( '[data-dob-year]' ); 73 var formEmbed = formWrapper.querySelector( '[data-contact-form-embed]' ); 74 var ageDenied = formWrapper.querySelector( '[data-contact-age-denied]' ); 75 var ageVerification = formWrapper.querySelector( '.contact-block__age-verification' ); 76 77 if ( ! monthSelect || ! daySelect || ! yearSelect || ! formEmbed ) { 78 return; 79 } 80 81 formWrapper.dataset.ageVerificationInitialized = 'true'; 82 83 function resetVerificationState() { 84 togglePanel( formEmbed, false ); 85 togglePanel( ageDenied, false ); 86 togglePanel( ageVerification, true ); 87 } 88 89 function verifyAge() { 90 var month = parseInt( monthSelect.value, 10 ); 91 var day = parseInt( daySelect.value, 10 ); 92 var year = parseInt( yearSelect.value, 10 ); 93 94 if ( ! month || ! day || ! year ) { 95 resetVerificationState(); 96 return; 97 } 98 99 var age = calculateAge( year, month, day ); 100 101 if ( age === null ) { 102 resetVerificationState(); 103 return; 104 } 105 106 if ( age >= MIN_AGE ) { 107 togglePanel( ageVerification, false ); 108 togglePanel( ageDenied, false ); 109 togglePanel( formEmbed, true ); 110 return; 111 } 112 113 togglePanel( ageVerification, true ); 114 togglePanel( formEmbed, false ); 115 togglePanel( ageDenied, true ); 116 } 117 118 monthSelect.addEventListener( 'change', verifyAge ); 119 daySelect.addEventListener( 'change', verifyAge ); 120 yearSelect.addEventListener( 'change', verifyAge ); 121 } 122 123 /** 124 * Initialize all contact block age verification instances. 125 */ 126 function initContactAgeVerification() { 127 var formWrappers = document.querySelectorAll( '[data-contact-age-verification]' ); 128 129 formWrappers.forEach( function( formWrapper ) { 130 initAgeVerification( formWrapper ); 131 } ); 132 } 133 134 if ( document.readyState === 'loading' ) { 135 document.addEventListener( 'DOMContentLoaded', initContactAgeVerification ); 136 } else { 137 initContactAgeVerification(); 138 } 139 140 // Re-init after ACF re-renders the block preview in the editor (e.g. once content is added). 141 if ( typeof window.acf !== 'undefined' ) { 142 window.acf.addAction( 'render_block_preview/type=contact-block', function () { 143 setTimeout( initContactAgeVerification, 50 ); 144 } ); 145 } 146})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.