Fix script and style tags being outside the fragment (and thus rendering
All checks were successful
Build And Deploy / build-and-deploy (push) Successful in 1m32s
All checks were successful
Build And Deploy / build-and-deploy (push) Successful in 1m32s
before <html> tag)
This commit is contained in:
parent
e80bbb9619
commit
ffdeab097f
1 changed files with 121 additions and 116 deletions
|
|
@ -26,124 +26,129 @@ const phoneValue = pickValue("phone");
|
||||||
const msgValue = pickValue("msg");
|
const msgValue = pickValue("msg");
|
||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
|
||||||
import Cap from "@cap.js/widget";
|
|
||||||
import "iconify-icon";
|
|
||||||
|
|
||||||
const captchaInput = document.querySelector("input[id='captcha']");
|
|
||||||
const captchaStatus = document.querySelector("#captchaStatus");
|
|
||||||
const statusText = captchaStatus?.querySelector("#statusText");
|
|
||||||
const initIcon = captchaStatus?.querySelector("#initIcon");
|
|
||||||
const completeIcon = captchaStatus?.querySelector("#completeIcon");
|
|
||||||
const errorIcon = captchaStatus?.querySelector("#errorIcon");
|
|
||||||
const progressIcon = captchaStatus?.querySelector("#progressIcon");
|
|
||||||
const cap = new Cap({
|
|
||||||
apiEndpoint: "/cap/",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (
|
|
||||||
captchaStatus &&
|
|
||||||
statusText &&
|
|
||||||
initIcon &&
|
|
||||||
completeIcon &&
|
|
||||||
errorIcon &&
|
|
||||||
progressIcon
|
|
||||||
) {
|
|
||||||
cap.addEventListener("solve", function (e) {
|
|
||||||
const humanness = Math.round((85 + Math.random() * 14.9) * 10) / 10;
|
|
||||||
statusText.textContent = `${humanness}% human. Good enough!`;
|
|
||||||
progressIcon.classList.add("hidden");
|
|
||||||
errorIcon.classList.add("hidden");
|
|
||||||
initIcon.classList.add("hidden");
|
|
||||||
completeIcon.classList.remove("hidden");
|
|
||||||
});
|
|
||||||
cap.addEventListener("error", function (e) {
|
|
||||||
statusText.textContent = "Oops! We crashed!";
|
|
||||||
progressIcon.classList.add("hidden");
|
|
||||||
completeIcon.classList.add("hidden");
|
|
||||||
initIcon.classList.add("hidden");
|
|
||||||
errorIcon.classList.remove("hidden");
|
|
||||||
});
|
|
||||||
cap.addEventListener("progress", (event) => {
|
|
||||||
statusText.textContent = `Weighing your humanity... ${event.detail.progress}%`;
|
|
||||||
errorIcon.classList.add("hidden");
|
|
||||||
completeIcon.classList.add("hidden");
|
|
||||||
initIcon.classList.add("hidden");
|
|
||||||
progressIcon.classList.remove("hidden");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (captchaInput && "value" in captchaInput) {
|
|
||||||
const { token } = await cap.solve();
|
|
||||||
captchaInput.value = token;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
form {
|
|
||||||
display: grid;
|
|
||||||
row-gap: var(--stack-large);
|
|
||||||
column-gap: var(--gutter-large);
|
|
||||||
width: 100%;
|
|
||||||
margin-inline: auto;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
grid-template-areas:
|
|
||||||
"header header"
|
|
||||||
"name phone"
|
|
||||||
"msg msg"
|
|
||||||
"captcha otp"
|
|
||||||
"lbtn rbtn";
|
|
||||||
}
|
|
||||||
#header {
|
|
||||||
grid-area: header;
|
|
||||||
}
|
|
||||||
label[for="name"] {
|
|
||||||
grid-area: name;
|
|
||||||
}
|
|
||||||
label[for="phone"] {
|
|
||||||
grid-area: phone;
|
|
||||||
}
|
|
||||||
label[for="msg"] {
|
|
||||||
grid-area: msg;
|
|
||||||
}
|
|
||||||
label[for="otp"] {
|
|
||||||
grid-area: otp;
|
|
||||||
}
|
|
||||||
label[for="captcha"] {
|
|
||||||
grid-area: captcha;
|
|
||||||
}
|
|
||||||
#captchaStatus {
|
|
||||||
padding-block: calc(2px + (var(--stack-small) * 1));
|
|
||||||
cursor: text;
|
|
||||||
}
|
|
||||||
#statusText {
|
|
||||||
margin-inline-start: 0.5rem;
|
|
||||||
}
|
|
||||||
button#reset {
|
|
||||||
grid-area: lbtn;
|
|
||||||
}
|
|
||||||
button#send_otp {
|
|
||||||
grid-area: lbtn;
|
|
||||||
}
|
|
||||||
button#send_msg {
|
|
||||||
grid-area: rbtn;
|
|
||||||
}
|
|
||||||
fieldset {
|
|
||||||
display: contents;
|
|
||||||
}
|
|
||||||
.spin {
|
|
||||||
animation: spin 4s linear infinite;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
@keyframes spin {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<Layout>
|
<Layout>
|
||||||
<title slot="head">Contact</title>
|
<title slot="head">Contact</title>
|
||||||
|
<script>
|
||||||
|
import Cap from "@cap.js/widget";
|
||||||
|
import "iconify-icon";
|
||||||
|
</script>
|
||||||
|
<script is:inline>
|
||||||
|
import Cap from "@cap.js/widget";
|
||||||
|
import "iconify-icon";
|
||||||
|
const captchaInput = document.querySelector("input[id='captcha']");
|
||||||
|
const captchaStatus = document.querySelector("#captchaStatus");
|
||||||
|
const statusText = captchaStatus?.querySelector("#statusText");
|
||||||
|
const initIcon = captchaStatus?.querySelector("#initIcon");
|
||||||
|
const completeIcon = captchaStatus?.querySelector("#completeIcon");
|
||||||
|
const errorIcon = captchaStatus?.querySelector("#errorIcon");
|
||||||
|
const progressIcon = captchaStatus?.querySelector("#progressIcon");
|
||||||
|
const cap = new Cap({
|
||||||
|
apiEndpoint: "/cap/",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
captchaStatus &&
|
||||||
|
statusText &&
|
||||||
|
initIcon &&
|
||||||
|
completeIcon &&
|
||||||
|
errorIcon &&
|
||||||
|
progressIcon
|
||||||
|
) {
|
||||||
|
cap.addEventListener("solve", function (e) {
|
||||||
|
const humanness = Math.round((85 + Math.random() * 14.9) * 10) / 10;
|
||||||
|
statusText.textContent = `${humanness}% human. Good enough!`;
|
||||||
|
progressIcon.classList.add("hidden");
|
||||||
|
errorIcon.classList.add("hidden");
|
||||||
|
initIcon.classList.add("hidden");
|
||||||
|
completeIcon.classList.remove("hidden");
|
||||||
|
});
|
||||||
|
cap.addEventListener("error", function (e) {
|
||||||
|
statusText.textContent = "Oops! We crashed!";
|
||||||
|
progressIcon.classList.add("hidden");
|
||||||
|
completeIcon.classList.add("hidden");
|
||||||
|
initIcon.classList.add("hidden");
|
||||||
|
errorIcon.classList.remove("hidden");
|
||||||
|
});
|
||||||
|
cap.addEventListener("progress", (event) => {
|
||||||
|
statusText.textContent = `Weighing your humanity... ${event.detail.progress}%`;
|
||||||
|
errorIcon.classList.add("hidden");
|
||||||
|
completeIcon.classList.add("hidden");
|
||||||
|
initIcon.classList.add("hidden");
|
||||||
|
progressIcon.classList.remove("hidden");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (captchaInput && "value" in captchaInput) {
|
||||||
|
const { token } = await cap.solve();
|
||||||
|
captchaInput.value = token;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
form {
|
||||||
|
display: grid;
|
||||||
|
row-gap: var(--stack-large);
|
||||||
|
column-gap: var(--gutter-large);
|
||||||
|
width: 100%;
|
||||||
|
margin-inline: auto;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
grid-template-areas:
|
||||||
|
"header header"
|
||||||
|
"name phone"
|
||||||
|
"msg msg"
|
||||||
|
"captcha otp"
|
||||||
|
"lbtn rbtn";
|
||||||
|
}
|
||||||
|
#header {
|
||||||
|
grid-area: header;
|
||||||
|
}
|
||||||
|
label[for="name"] {
|
||||||
|
grid-area: name;
|
||||||
|
}
|
||||||
|
label[for="phone"] {
|
||||||
|
grid-area: phone;
|
||||||
|
}
|
||||||
|
label[for="msg"] {
|
||||||
|
grid-area: msg;
|
||||||
|
}
|
||||||
|
label[for="otp"] {
|
||||||
|
grid-area: otp;
|
||||||
|
}
|
||||||
|
label[for="captcha"] {
|
||||||
|
grid-area: captcha;
|
||||||
|
}
|
||||||
|
#captchaStatus {
|
||||||
|
padding-block: calc(2px + (var(--stack-small) * 1));
|
||||||
|
cursor: text;
|
||||||
|
}
|
||||||
|
#statusText {
|
||||||
|
margin-inline-start: 0.5rem;
|
||||||
|
}
|
||||||
|
button#reset {
|
||||||
|
grid-area: lbtn;
|
||||||
|
}
|
||||||
|
button#send_otp {
|
||||||
|
grid-area: lbtn;
|
||||||
|
}
|
||||||
|
button#send_msg {
|
||||||
|
grid-area: rbtn;
|
||||||
|
}
|
||||||
|
fieldset {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
.spin {
|
||||||
|
animation: spin 4s linear infinite;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
@keyframes spin {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<Fragment slot="content">
|
<Fragment slot="content">
|
||||||
<h2>Contact</h2>
|
<h2>Contact</h2>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue