Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track custom events being $dispatch-ed #48

Open
HugoDF opened this issue May 9, 2020 · 9 comments
Open

Track custom events being $dispatch-ed #48

HugoDF opened this issue May 9, 2020 · 9 comments
Labels
enhancement New feature or request

Comments

@HugoDF
Copy link
Collaborator

HugoDF commented May 9, 2020

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 #48 (comment)):

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

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.

@HugoDF HugoDF added the enhancement New feature or request label May 9, 2020
@HugoDF
Copy link
Collaborator Author

HugoDF commented Nov 23, 2020

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

@ryangjchandler
Copy link
Contributor

When you say hook in, do you mean monkey-patching the prototype?

@HugoDF
Copy link
Collaborator Author

HugoDF commented Nov 23, 2020

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?

@ryangjchandler
Copy link
Contributor

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?

@ryangjchandler
Copy link
Contributor

I think we should do the page -> devtools communication refactor first.

@HugoDF
Copy link
Collaborator Author

HugoDF commented Nov 23, 2020

@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 😂

@ryangjchandler
Copy link
Contributor

@HugoDF Legendary, hadn't even thought about that.

@ryangjchandler ryangjchandler added this to the v0.1.0 [unreleased] milestone Nov 23, 2020
@KevinBatdorf
Copy link
Contributor

It turns out that it's possible to overwrite a magic property 👀

Oh nice! We can implement both $refs and $dispatch both now :D

@HugoDF
Copy link
Collaborator Author

HugoDF commented Nov 27, 2020

It turns out that it's possible to overwrite a magic property 👀

Oh nice! We can implement both $refs and $dispatch both 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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants