1class Recaptcha { 2 /** 3 * @type {string} 4 */ 5 fieldSelector = '[data-recaptcha-form-field]'; 6 7 /** 8 * @type {HTMLFormElement} 9 */ 10 form = null; 11 12 /** 13 * @type {HTMLInputElement} 14 */ 15 field = null; 16 17 /** 18 * @type {string} 19 */ 20 response = ''; 21 22 /** 23 * @param {HTMLFormElement} form 24 */ 25 constructor(form) { 26 this.initializeElements(form); 27 this.initializeEvents(); 28 this.registerCallback(); 29 } 30 31 /** 32 * @param {HTMLFormElement} form 33 */ 34 initializeElements(form) { 35 this.form = form; 36 this.field = this.form.querySelector(this.fieldSelector); 37 } 38 39 initializeEvents() { 40 // used with visible recaptcha 41 [...this.form.querySelectorAll('[data-recaptcha-form-submit]')] 42 .map(button => button.addEventListener('click', event => this.visibleRecaptchaButtonClicked(event))); 43 } 44 45 /** 46 * @param {PointerEvent} event 47 */ 48 visibleRecaptchaButtonClicked(event) { 49 if (!this.form.reportValidity()) { 50 event.preventDefault(); 51 } 52 } 53 54 /** 55 * @return {boolean} 56 */ 57 recaptchaFieldValid() { 58 return this.field.value !== '' && this.field.value === this.response; 59 } 60 61 registerCallback() { 62 // for box recaptcha 63 window.onRecaptchaCallback = (response) => this.callback(response); 64 window.onRecaptchaExpired = () => this.recaptchaExpired(); 65 window.onRecaptchaError = () => this.recaptchaError(); 66 // for invisible recaptcha 67 window.onRecaptchaSubmit = (response) => this.submitForm(response); 68 } 69 70 /** 71 * @param {string} response 72 */ 73 submitForm(response) { 74 this.response = response; 75 this.field.value = response; 76 if (this.form.reportValidity() && this.recaptchaFieldValid()) { 77 this.form.submit(); 78 } 79 } 80 81 /** 82 * @param {string} response 83 */ 84 callback(response) { 85 this.response = response; 86 this.field.value = response; 87 } 88 89 recaptchaExpired() { 90 this.response = ''; 91 this.field.value = ''; 92 } 93 94 recaptchaError() { 95 this.response = ''; 96 this.field.value = ''; 97 } 98 99 static initializeForms() { 100 [...document.querySelectorAll('form .g-recaptcha')] 101 .map(element => { 102 const form = element.closest('form'); 103 new Recaptcha(form); 104 }) 105 } 106} 107Recaptcha.initializeForms();
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.