kopia lustrzana https://github.com/wagtail/wagtail
Add sendBeacon support to ActionController
rodzic
5168ee0c7c
commit
54f12e6354
|
@ -44,7 +44,7 @@ describe('ActionController', () => {
|
|||
</button>`);
|
||||
});
|
||||
|
||||
it('it should allow for a form POST with created data', () => {
|
||||
it('should allow for a form POST with created data', () => {
|
||||
const btn = document.querySelector('[data-controller="w-action"]');
|
||||
const submitMock = jest.fn();
|
||||
window.HTMLFormElement.prototype.submit = submitMock;
|
||||
|
@ -59,6 +59,44 @@ describe('ActionController', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('sendBeacon method', () => {
|
||||
beforeEach(async () => {
|
||||
await setup(`
|
||||
<button
|
||||
data-controller="w-action"
|
||||
data-action="blur->w-action#sendBeacon"
|
||||
data-w-action-url-value="https://analytics.example/not-interested"
|
||||
>
|
||||
If you move focus away from this button, a POST request will be sent.
|
||||
</button>
|
||||
<button id="other-button">Other button</button>
|
||||
`);
|
||||
});
|
||||
|
||||
it('should send a POST request using sendBeacon with the CSRF token included', () => {
|
||||
const sendBeaconMock = jest.fn();
|
||||
Object.defineProperty(window.navigator, 'sendBeacon', {
|
||||
value: sendBeaconMock,
|
||||
});
|
||||
|
||||
const btn = document.querySelector('[data-controller="w-action"]');
|
||||
const otherBtn = document.getElementById('other-button');
|
||||
btn.focus();
|
||||
otherBtn.focus();
|
||||
|
||||
expect(sendBeaconMock).toHaveBeenCalledTimes(1);
|
||||
expect(sendBeaconMock).toHaveBeenCalledWith(
|
||||
'https://analytics.example/not-interested',
|
||||
expect.any(FormData),
|
||||
);
|
||||
|
||||
const formData = sendBeaconMock.mock.lastCall[1];
|
||||
expect(
|
||||
Object.fromEntries(formData.entries()).csrfmiddlewaretoken,
|
||||
).toEqual('potato');
|
||||
});
|
||||
});
|
||||
|
||||
describe('click method', () => {
|
||||
beforeEach(async () => {
|
||||
await setup(`
|
||||
|
|
|
@ -26,6 +26,11 @@ import { WAGTAIL_CONFIG } from '../config/wagtailConfig';
|
|||
* Enable
|
||||
* </button>
|
||||
*
|
||||
* @example - triggering a POST request via sendBeacon
|
||||
* <button data-controller="w-action" data-action="blur->w-action#sendBeacon">
|
||||
* If you move focus away from this button, a POST request will be sent.
|
||||
* </button>
|
||||
*
|
||||
* @example - triggering a dynamic redirect
|
||||
* // note: a link is preferred normally
|
||||
* <form>
|
||||
|
@ -71,10 +76,7 @@ export class ActionController extends Controller<
|
|||
*/
|
||||
noop() {}
|
||||
|
||||
post(event: Event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
private createFormElement() {
|
||||
const formElement = document.createElement('form');
|
||||
|
||||
formElement.action = this.urlValue;
|
||||
|
@ -97,10 +99,26 @@ export class ActionController extends Controller<
|
|||
formElement.appendChild(nextElement);
|
||||
}
|
||||
|
||||
return formElement;
|
||||
}
|
||||
|
||||
post(event: Event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
const formElement = this.createFormElement();
|
||||
document.body.appendChild(formElement);
|
||||
formElement.submit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Like post, but uses the Beacon API, which can be used to send data
|
||||
* to a server without waiting for a response. Useful for sending analytics
|
||||
* data or a "release" signal before navigating away from a page.
|
||||
*/
|
||||
sendBeacon() {
|
||||
navigator.sendBeacon(this.urlValue, new FormData(this.createFormElement()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a redirect based on the custom event's detail, the Stimulus param
|
||||
* or finally check the controlled element for a value to use.
|
||||
|
|
Ładowanie…
Reference in New Issue