alpinejs-devtools
alpinejs-devtools copied to clipboard
Track custom events being `$dispatch`-ed
This is again inspired by Vue.js Devtool's "events" tab, obviously Alpine.js doesn't use synthetic events or emit events to communicate between components.
~~Instead we should register a top-level listener for events being dispatched with $dispatch (which we can detect) eg. we can read @click="$dispatch('my-custom-event') which means we should listen to 'my-custom-event' at the top-level (using document.addEventListener) and then report their contents in a tab.~~
Any thoughts/ideas limitations you can think of @ryangjchandler @Te7a-Houdini ?
We probably want a new panel for this.
Update 1
With Alpine latest we can overwrite $dispatch and instrument it (see https://github.com/amaelftah/alpinejs-devtools/issues/48#issuecomment-732133163):
It turns out that it's possible to overwrite a magic property 👀 , so we can inject some code that will replace
$dispatchand send debug info on call 👍 https://codepen.io/hugodf/pen/xxOvqpg
Note on this: we should check that the suggested $dispatch function override works the same as regular Alpine one, one thing that might be different is which element dispatchEvent is being called on
Update 2
Overwriting $dispatch doesn't behave the same as Alpine implementation see https://codepen.io/hugodf/pen/GRjKgNO?editors=1111 the overriden $event.target is not correct (it's the root of the component, not the element from which $dispatch is called).
A way to get this to work is to monkey-patch dispatchEvent with something like this:
const _dispatchEvent = EventTarget.prototype.dispatchEvent;
EventTarget.prototype.dispatchEvent = function(...args) {
// send a message to devtools
// `this` is the element from which `$dispatch` is called
// `args[0]` is the event name, `args[1]` is the options (including `options.detail`)
console.log(this, args);
return _dispatchEvent.apply(this, args);
}
This has the advantage of not being Alpine.js specific (eg. if custom events are sent from vanilla JS) + not locking us into a minimum Alpine version.
Here's the relevant code in Alpine, if we can hook into CustomEvent or el.dispatchEvent that could work
https://github.com/alpinejs/alpine/blob/3c3e8b801a7b00a982dd54290cf656f051e915d9/src/component.js#L369
When you say hook in, do you mean monkey-patching the prototype?
When you say hook in, do you mean monkey-patching the prototype?
Pretty much hahaha
Otherwise we would have to read the DOM and parse custom event names since I don't think you can just register a catch-all event handler for it.
Other ways we could go is a change in the Alpine side which detects devtools and integrates that way or maybe overwriting the $dispatch magic property somehow?
When you say hook in, do you mean monkey-patching the prototype?
Pretty much hahaha
Yeah, I think that could work. Would just be a case of extending EventTarget.dispatchEvent and checking that the element in question has a parent or itself with __x property?
I think we should do the page -> devtools communication refactor first.
@ryangjchandler Agreed re- the refactor.
It turns out that it's possible to overwrite a magic property 👀 , so we can inject some code that will replace $dispatch and send debug info on call 👍
https://codepen.io/hugodf/pen/xxOvqpg
Other interesting note is that $dispatch basically doesn't need to be in core any more 😂
@HugoDF Legendary, hadn't even thought about that.
It turns out that it's possible to overwrite a magic property 👀
Oh nice! We can implement both $refs and $dispatch both now :D
It turns out that it's possible to overwrite a magic property 👀
Oh nice! We can implement both
$refsand$dispatchboth now :D
well see this update
Overwriting $dispatch doesn't behave the same as Alpine implementation see https://codepen.io/hugodf/pen/GRjKgNO?editors=1111 the overriden $event.target is not correct (it's the root of the component, not the element from which $dispatch is called).