1textareaElement = document.getElementById("text-to-copy"); 2 3genform.addEventListener("submit", function(event){ 4 event.preventDefault(); 5 6 // First, validate the form 7 var didValidationFail = false; 8 var contactInputElements = document.getElementById('contact').getElementsByTagName('input'); 9 10 for (var i = 0; i < contactInputElements.length; i++) { 11 var inputEl = contactInputElements[i]; 12 checkContactValidity(inputEl); 13 14 if (!isContactValid(inputEl)) { 15 inputEl.focus(); 16 didValidationFail = true; 17 } 18 } 19 20 if (didValidationFail) { 21 document.getElementById('validation-errors-box').classList.remove('is-hidden'); 22 return; 23 } else { 24 document.getElementById('validation-errors-box').classList.add('is-hidden'); 25 } 26 27 generate('security.txt', [ 28 "contact", "expires", "encryption", "acknowledgments", "preferredLanguages", "canonical", "policy", "hiring", "csaf" 29 ]); 30 31 scrollToStepTwo() 32}); 33 34// Convert a date string and time string into a string compliant with the RFC 35function formatDate(dateString, timeString) { 36 // The replace operation is for Safari compatibility: it can only parse YYYY/MM/DD dates and most 37 // other browsers support both YYYY-MM-DD and YYYY/MM/DD. 38 var date = new Date(dateString.replace(/-/g, '/') + ' ' + timeString); 39 40 return date.toISOString(); 41} 42 43function generate(filename, field_array){ 44 var text = ""; 45 46 // Converts camel case like 'abcDefGhi' into 47 // the format 'Abc-Def-Ghi' 48 function camelToHyphen(camelCaseWord) { 49 // introduce the special case for CSAF (short term solution) 50 if (camelCaseWord === "csaf") {return "CSAF"} 51 52 var components = camelCaseWord.split(/(?=[A-Z])/) // abcDef => [abc, Def] 53 54 return components.map(function (component) { 55 return component[0].toUpperCase() + component.slice(1) // ABC => Abc 56 }).join('-') 57 } 58 59 field_array.forEach(function(e){ 60 console.log(e) 61 62 if (e == "expires") { 63 var dateInput = document.getElementById(e).querySelector("[type='date']"); 64 var timeInput = document.getElementById(e).querySelector("[type='time']"); 65 66 text += camelToHyphen(e) + ": " + formatDate(dateInput.value, timeInput.value) + "\n"; 67 } else { 68 var inputs = document.getElementById(e).querySelector(".list-of-inputs") 69 inputs.querySelectorAll("input").forEach(function(child) { 70 if(child.value.length > 0){ 71 text += camelToHyphen(e) + ": " + child.value + "\n"; 72 } 73 }); 74 } 75 }); 76 77 textareaElement.value = text; 78 79 if (document.queryCommandSupported("copy")) { 80 document.getElementById("copy-button").removeAttribute("disabled") 81 } 82} 83 84function addAlternative(button) { 85 var list = button.parentElement.parentElement.parentElement.querySelector(".list-of-inputs") 86 87 var newInput = document.createElement("INPUT") 88 newInput.setAttribute("placeholder", "Another possible alternative") 89 newInput.setAttribute("class", "input") 90 91 var newInputControl = document.createElement("DIV") 92 newInputControl.setAttribute("class", "control is-expanded") 93 newInputControl.appendChild(newInput) 94 95 if (button.parentElement.parentElement.parentElement.id === 'contact') { 96 newInput.addEventListener('change', function () { autoprefixEmail(newInput); }); 97 98 var errorMessage = document.createElement('P'); 99 newInputControl.appendChild(errorMessage); 100 errorMessage.textContent = 'Each contact field must begin with https:// for web URIs; tel: for telephone numbers; or mailto: for e-mails.'; 101 102 var ERROR_MESSAGE_CLASSES = ['is-danger', 'is-hidden', 'help'] 103 104 for (var i = 0; i < ERROR_MESSAGE_CLASSES.length; i++) { 105 errorMessage.classList.add(ERROR_MESSAGE_CLASSES[i]) 106 } 107 } 108 109 var removeButton = document.createElement("BUTTON") 110 removeButton.setAttribute("type", "button") 111 removeButton.setAttribute("class", "button is-danger") 112 removeButton.textContent = "Remove" 113 114 var removeButtonControl = document.createElement("DIV") 115 removeButtonControl.setAttribute("class", "control") 116 removeButtonControl.appendChild(removeButton) 117 118 var overallField = document.createElement("LI") 119 overallField.setAttribute("class", "field is-grouped") 120 overallField.appendChild(newInputControl) 121 overallField.appendChild(removeButtonControl) 122 123 removeButton.addEventListener("click", function() { 124 // not using Element.remove() to maintain support 125 // with Internet Explorer 126 overallField.parentNode.removeChild(overallField) 127 }) 128 129 list.appendChild(overallField) 130 newInput.focus() 131} 132 133function copyTextarea(){ 134 textareaElement.select(); 135 document.execCommand("copy"); 136 137 window.getSelection().empty(); 138 showNotification(); 139} 140 141function scrollToStepTwo() { 142 var stepTwo = document.getElementById("step-two") 143 144 if (stepTwo.scrollIntoView) { 145 stepTwo.scrollIntoView({behavior: "smooth", block: "start"}) 146 } else { 147 location.hash = "step-two" 148 } 149} 150 151notification = document.getElementById("txt-notification"); 152 153function removeNotification(){ 154 function hide(){ 155 notification.classList.remove("visible"); 156 notification.removeEventListener("transitionend ", hide); 157 }; 158 159 notification.classList.remove("opaque"); 160 notification.addEventListener("transitionend", hide) 161} 162 163function showNotification(){ 164 notification.classList.add("visible"); 165 setTimeout(function(){ 166 // doesn't work when called on the same tick 167 notification.classList.add("opaque"); 168 }); 169} 170 171function isContactValid(el) { 172 var VALIDATION_REGEX = /^(mailto:|https:\/\/|tel:)/i; 173 174 return VALIDATION_REGEX.test(el.value); 175} 176 177function checkContactValidity(el) { 178 if (isContactValid(el)) { 179 el.parentElement.getElementsByTagName("p")[0].classList.add('is-hidden'); 180 el.classList.remove('is-danger'); 181 } else { 182 el.parentElement.getElementsByTagName("p")[0].classList.remove('is-hidden') 183 el.classList.add('is-danger'); 184 } 185} 186 187function autoprefixEmail(inputEl) { 188 // Add mailto: prefix, e.g. [email protected] -> mailto:[email protected] 189 190 // NOTE: If this regular expression is changed in future, it should always fail if 191 // the user enters some other schema (e.g. https://) so they always have the option of overriding it. 192 // Currently this is achieved by not allowing a colon to appear in the input. 193 if (/^[a-z0-9_+.-]+@[a-z0-9_+.-]+$/i.test(inputEl.value)) { 194 inputEl.value = 'mailto:' + inputEl.value; 195 } 196 197 checkContactValidity(inputEl); // potentially remove validation error if issue resolved 198}
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.