class NoblogsCf_FormKnownError extends Error{ } class NoblogsCf_Form{ /* * The button used to send the form message. */ #button = document.getElementById("noblogscf-form-button"); /* * True if the message is being sent, false otherwise. */ #sending = false; /* * The element containing the message sending status. Initially * empty, it starts to change after clicking on the button. */ #status = document.getElementById("noblogscf-form-status"); /* * The status text. */ #statusText = document.getElementById("noblogscf-form-status-text"); /* * Shows the form and attaches an action to the activation of the * button. */ constructor(){ // hide the instructions for users with Javascript disabled and show the form document.getElementById("noblogscf-no-javascript-instructions").style.display = "none"; // set the button type to "button" to prevent it from submitting the form this.#button.type = "button"; // send the message when the button is activated this.#button.addEventListener("click", this.#sendMessage.bind(this)); } /* * Encrypts and sends the form message if it isn't already being * sent. */ async #sendMessage(){ // if the message isn't being sent if(this.#sending === false){ try{ // the message is being sent this.#sending = true; this.#setStatus(wp.i18n.__("Sending…", "noblogs-contact-form")); // disable the button to prevent the user to try to send the message again while it is being sent this.#button.disabled = true; // set the unencrypted message const unencryptedMessage = document.getElementById("noblogscf-form-message").value; // check the unencrypted message isn't empty if(unencryptedMessage.length === 0){ throw new NoblogsCf_FormKnownError(wp.i18n.__("The message is empty.", "noblogs-contact-form")); } // encrypt the message var encryptedMessage = null; try{ encryptedMessage = await openpgp.encrypt({ message: await openpgp.createMessage({"text": unencryptedMessage}), encryptionKeys: await openpgp.readKey({"armoredKey": noblogscfPhpVars.pgpPublicKey}) }); } catch(error){ if(error.message === "Error encrypting message: Primary key is expired"){ throw new NoblogsCf_FormKnownError(wp.i18n.__("The PGP public key configured by the site manager has expired.", "noblogs-contact-form")); } else{ throw new NoblogsCf_FormKnownError(wp.i18n.__("The site manager has configured an invalid PGP public key.", "noblogs-contact-form")); } } // send the request var response = null; try{ response = await window.fetch(noblogscfPhpVars.requestURL, { "method": "post", "headers": { "Content-Type": "application/x-www-form-urlencoded", }, "body": "_ajax_nonce=" + noblogscfPhpVars.nonce + "&action=noblogscf_send_message_with_javascript&message=" + encodeURIComponent(encryptedMessage) }); } catch(error){ throw new NoblogsCf_FormKnownError(wp.i18n.__("Network error.", "noblogs-contact-form")) } // the message was sent if(response.ok && response.status === 200){ this.#setStatus(wp.i18n.__("Sent successfully!", "noblogs-contact-form")); } // the message was not sent else{ const responseBody = await response.json(); throw new NoblogsCf_FormKnownError(responseBody.data.error); } } catch(error){ // known error if(error instanceof NoblogsCf_FormKnownError){ this.#setErrorStatus(error.message); } // unknown error else{ this.#setErrorStatus(wp.i18n.__("Unknown.", "noblogs-contact-form")); } // re-enable the button to allow the user to try to send the message again this.#button.disabled = false; } // the message isn't being sent anymore this.#sending = false; } } /* * Sets the status text to an error status. */ #setErrorStatus(errorText){ // translators: "%s" is replaced with the reason why sending the message failed this.#setStatus(wp.i18n.sprintf(wp.i18n.__("Sending failed. Reason: %s", "noblogs-contact-form"), errorText)); } /* * Sets the status text. */ #setStatus(text){ // show the status this.#status.style.display = "block"; // change the status text this.#statusText.innerHTML = text; } }; // instantiate the class on the window load event window.addEventListener("load", () => { const noblogsCfForm = new NoblogsCf_Form(); });