-
Notifications
You must be signed in to change notification settings - Fork 154
[WIP] gloo-events #42
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
Conversation
Also, what name should we use for the string for the event type? Right now I call it EDIT: I went ahead and renamed it to |
Also, right now it only accepts |
I think that is fine, since the high-level, static API doesn't handle dynamic event listening, so it makes sense to have both, IMO. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good -- just need to get all the docs in place, rustfmt
, and double check each of the check list items over here: https://github.com/rustwasm/gloo/blob/master/CONTRIBUTING.md#gloo-crate-checklist
Thanks @Pauan!
@fitzgen Before I can fix this up, I think we need to resolve these two issues: |
Sounds like a perfect opportunity to use |
@fitzgen I don't think that works, since The goal is to be able to dynamically create a |
The lifetime can be // assuming this signature:
impl<'a> EventListener<'a> {
pub fn new<S, F>(target: &EventTarget, event_type: S, callback: F) -> Self
where
S: Into<Cow<'a, str>>,
F: FnMut(Event) + 'static,
{ ... }
}
// Enables both
EventListener::new(&target, "click", |event| { ... });
// and
let s: String = ...;
EventListener::new(&target, s, |event| { ... }); We could remove the The other option would be adding the |
@fitzgen Interesting, I hadn't seen that That does mean that all dynamic event types must be But as you say, allowing for |
Something new I just discovered: It is apparently possible to significantly improve the performance of the browser by setting The only downside is that now you cannot call My thinking is that we should make @fitzgen Any thoughts on this? |
I think that the mid-level API probably shouldn't be as opinionated as that, but maybe the higher-level API could be. I think we want an Orthogonal to the expressive ability to define event listener options: As another layer, the |
To be clear, we're just discussing the defaults. Right now the browsers will default to The reason the browsers have (started to) default to The only reason the browsers aren't always defaulting to What you're suggesting is essentially that the easy way should incur significant performance costs (even if the event listener doesn't actually use What I'm suggesting is that the easy way should be fast, and that the user should go out of their way to enable
Agreed.
Also agreed, I think that's a good idea. |
Ok, I'm convinced. |
@fitzgen Okay, great, I think that nails down all the design elements, so I'll try to get this finished ASAP, since I know it's blocking other work. |
@fitzgen I fixed all the issues that were brought up. I'm very happy with both the API and the implementation, but I want to make sure we have consensus that this is the right public API before I do the hard work of adding in docs and unit tests. In particular, I'm not so sure about Implementation-wise, since |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API looks good! Let's get those docs and tests written :)
Just to clarify the status of this: I just need to put crate-level docs and add some docs to the guide and this'll be ready for review. |
Okay, this is basically done, and ready for the final review. I made some API changes since the previous review:
I added in unit tests, and docs for everything, but I wasn't sure what to put into the Gloo Guide... the other crates have an empty entry in the Guide, and wouldn't it just be repeating the crate-level docs...? |
(By the way, my intention is to make the change from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! Most of my feedback is just documentation wording nitpicks :-p
The one more tangible suggestion is that I think we should have a test that event listeners are removed on drop properly:
- add event listener A with function F
- add event listener B with function G
- fire event
- assert both F and G observed the event
- remove listener A
- fire event
- assert F observed the event and G did not
- add event listener C with function G
- fire event
- assert both F and G observed the event
Thanks @Pauan!
}) | ||
} | ||
|
||
// TODO is it possible to somehow cleanup the closure after a timeout? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could add raw
getters for the underlying closure's js_sys::Function
, and then use web-sys
manually to remove the listener. This doesn't clean up the Rust closure, however. Probably that's alright (particularly since it isn't actually closing over anything, and therefore should just be a fn
pointer).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and then use web-sys manually to remove the listener.
Since it's attached to a <div>
element which doesn't exist in the DOM, the event listeners themself will already be automatically cleaned up (by the browser and JS's GC).
So the comment was just about the Rust Closure memory.
@fitzgen I debated whether to post this in the RFC thread, but since it's a (relatively) small change I decided to just go ahead and do it. The
I'm quite happy with this, now there is a nice symmetry:
And the I think this makes the API incredibly clear for users (it's much simpler now), and it also now allows for using (I also fixed the suggestions and added some more unit tests, so this is ready for the final final review.) |
…ons by reference (since it's Copy anyways)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything looks good modulo one comment below about once_with_options
} | ||
|
||
#[inline] | ||
fn to_js(&self, once: bool) -> AddEventListenerOptions { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok, I see now. Apologies my last review was submitted quickly before I had to run off on an errand.
If this was a public API, I'd advocate for replacing the bool with a more meaningful enum, but it isn't pub so I think the bool is fine.
I think this is ready to merge now? Am I missing anything that makes it still [WIP] as the title implies? |
Do not merge yet!
Since the current plan is to create a high-level statically typed events system, what should we do with this mid-level API?
I think it makes sense for the high-level and mid-level API to both go into the
gloo-events
crate, but should we putEventListener
into a submodule? Or is it okay to leave it at the root? Will that confuse users?Fixes #30