1(function () { 2 'use strict'; 3 4 function initNavigation() { 5 const toggle = document.querySelector('.marketing-nav__toggle'); 6 const menu = document.querySelector('#marketingNavigation'); 7 if (!toggle || !menu) { 8 return; 9 } 10 11 document.addEventListener('keydown', function (event) { 12 if (event.key !== 'Escape' || toggle.getAttribute('aria-expanded') !== 'true') { 13 return; 14 } 15 16 toggle.click(); 17 toggle.focus(); 18 }); 19 } 20 21 function initDisclosureStates() { 22 const compactLayout = window.matchMedia('(max-width: 991px)'); 23 const responsiveDisclosures = document.querySelectorAll('.marketing-monitor-disclosure, .marketing-pricing-disclosure'); 24 25 function syncResponsiveDisclosures() { 26 responsiveDisclosures.forEach(function (details) { 27 details.open = !compactLayout.matches; 28 }); 29 } 30 31 syncResponsiveDisclosures(); 32 compactLayout.addEventListener('change', syncResponsiveDisclosures); 33 34 document.querySelectorAll('details > summary').forEach(function (summary) { 35 const details = summary.parentElement; 36 summary.setAttribute('aria-expanded', details.open ? 'true' : 'false'); 37 details.addEventListener('toggle', function () { 38 summary.setAttribute('aria-expanded', details.open ? 'true' : 'false'); 39 }); 40 }); 41 } 42 43 function normalizeUrl(input) { 44 const value = input.value.trim(); 45 if (value && !/^https?:\/\//i.test(value)) { 46 input.value = 'https://' + value; 47 } 48 } 49 50 function setCommandStatus(input, message, state) { 51 const form = input.closest('.js-marketing-command'); 52 form.querySelector('.marketing-command__status').textContent = message; 53 form.classList.toggle('is-success', state === 'success'); 54 form.classList.toggle('is-error', state === 'error'); 55 input.setAttribute('aria-invalid', state === 'error' ? 'true' : 'false'); 56 } 57 58 function validateUrl(input) { 59 normalizeUrl(input); 60 if (!input.value) { 61 setCommandStatus(input, '', ''); 62 return; 63 } 64 65 try { 66 const url = new URL(input.value); 67 const valid = Boolean(url.hostname); 68 setCommandStatus(input, valid ? 'Ready to analyze.' : 'Enter a valid website URL.', valid ? 'success' : 'error'); 69 } catch { 70 setCommandStatus(input, 'Enter a valid website URL.', 'error'); 71 } 72 } 73 74 function bindModeSelection(form) { 75 const modes = form.querySelectorAll('.js-marketing-mode'); 76 const modeValue = form.querySelector('.js-marketing-mode-value'); 77 const submit = form.querySelector('.js-marketing-submit'); 78 const submitLabel = form.querySelector('.js-marketing-submit-label'); 79 80 modes.forEach(function (mode) { 81 mode.addEventListener('click', function () { 82 modes.forEach(function (item) { 83 item.classList.remove('marketing-mode--active'); 84 item.setAttribute('aria-pressed', 'false'); 85 }); 86 87 mode.classList.add('marketing-mode--active'); 88 mode.setAttribute('aria-pressed', 'true'); 89 modeValue.value = mode.dataset.mode; 90 form.action = form.dataset[mode.dataset.mode + 'Action']; 91 submit.dataset.defaultLabel = mode.dataset.label; 92 submitLabel.textContent = mode.dataset.label; 93 }); 94 }); 95 } 96 97 function bindUrlStates(form) { 98 const input = form.querySelector('input[name="url"]'); 99 input.addEventListener('input', function () { 100 setCommandStatus(input, '', ''); 101 }); 102 input.addEventListener('blur', function () { 103 validateUrl(input); 104 }); 105 input.addEventListener('invalid', function () { 106 setCommandStatus(input, 'Enter a website URL to start the analysis.', 'error'); 107 }); 108 } 109 110 function bindSubmitLoading(form) { 111 const submit = form.querySelector('.js-marketing-submit'); 112 const submitLabel = form.querySelector('.js-marketing-submit-label'); 113 form.addEventListener('submit', function () { 114 normalizeUrl(form.querySelector('input[name="url"]')); 115 submit.disabled = true; 116 submit.classList.add('is-loading'); 117 submitLabel.textContent = 'Starting analysis'; 118 }, true); 119 } 120 121 function initCommand() { 122 const form = document.querySelector('.js-marketing-command'); 123 if (!form) { 124 return; 125 } 126 127 bindModeSelection(form); 128 bindUrlStates(form); 129 bindSubmitLoading(form); 130 } 131 132 initNavigation(); 133 initDisclosureStates();
134 initCommand(); 135})();
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.