|
import React, { useRef, useEffect } from "react"; |
|
import Button from "./Button"; |
|
import type { ButtonProps } from "./Button"; |
|
|
|
import { useAuthTokenFromContext } from "../AuthProvider"; |
|
|
|
export const HttpButton = ({ |
|
children, |
|
action, |
|
enctype = "application/x-www-form-urlencoded", |
|
method = "get", |
|
tokenType = "csrf", |
|
...props }: { |
|
action: string, |
|
enctype?: "multipart/form-data" | "application/x-www-form-urlencoded", |
|
method: "post" | "get" | "put" | "delete" | "patch", |
|
tokenType: "csrf" | "link" |
|
} & ButtonProps) => { |
|
const token = useAuthTokenFromContext(tokenType); |
|
const trackingInputRef = useRef<HTMLButtonElement | null>(null); |
|
|
|
useEffect(() => { |
|
const onTrackingActivated = (event) => { |
|
const srcElement = event.currentTarget; |
|
const rltdElement = event.relatedTarget |
|
if (rltdElement !== null && srcElement.form === rltdElement) { |
|
const trckrElement = srcElement.form.querySelector('[id="pointer_tracker"]'); |
|
trckrElement.value = "on"; |
|
} |
|
}; |
|
|
|
if (trackingInputRef.current) { |
|
trackingInputRef.current.addEventListener("pointerenter", onTrackingActivated, false); |
|
} |
|
|
|
return () => { |
|
if (trackingInputRef.current) { |
|
trackingInputRef.current.removeEventListener("pointerenter", onTrackingActivated, false); |
|
} |
|
} |
|
}, []); |
|
|
|
return ( |
|
<form credentialless action={action} accept-charset="UTF-8" method={"get"} enctype={enctype} noValidate> |
|
{/* Method spoofing ... */} |
|
{ |
|
method !== "get" |
|
? <input type="hidden" name="_method" value={method} autocomplete="off"> |
|
: null |
|
} |
|
<input type="hidden" name="authenticity_token" value={token}> |
|
<input type="hidden" name="pointer_event_tracking" id="pointer_tracker" value="off"> |
|
<input type="hidden" name="bot_honeypot" value=""> |
|
<Button type="submit" class={className} {...props} ref={trackingInputRef}> |
|
{children} |
|
</Button> |
|
</form> |
|
); |
|
}; |