-
-
Notifications
You must be signed in to change notification settings - Fork 28
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
More event props improvements #9
Conversation
23467b5
to
74750b4
Compare
@@ -10,5 +10,5 @@ trait ErrorEventProps[EP[_ <: DomEvent], DomEvent, DomErrorEvent <: DomEvent] { | |||
/** | |||
* Script to be run when an error occurs when the file is being loaded | |||
*/ | |||
lazy val onError: EP[DomErrorEvent] = eventProp("onerror") |
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.
Oopsie. Good catch
/** | ||
* Fires when the browser window is resized | ||
*/ | ||
lazy val onResize: EP[DomUIEvent] = eventProp("resize") |
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.
Why do you want to move onResize
to this trait? Is it somehow conceptually different from other events in WindowEventProps
? Looking at MDN this event seems to be window-specific by nature.
Looking at onLoad
and onScroll
, I see that they can be applied to elements as well. It would be nice to update the comments on those to not be window-specific and to link to https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload and https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onscroll
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.
The reason is that I want to separate event handlers that are exclusive to Window
, Document
, Element
and HTMLElement
. All three of them implement GlobalEventHandlers
. And, for example the event handler onResize
is a GlobalEventHandler
and therefore not exclusive to Window
(eventhough the resize event only exists on Window).
But here they differ:
Window
additionally implementsWindowEventHandlers
and its own event handlers, which more or less corresponds to ourWindowEventProps
(these properties are not available onDocument
orElement
).Document
also adds some own event handlers. We currently do not have event properties for those.Element
has two event handler of its own. We currently do not have event properties for those.HTMLElement
adds the clipboard and touch events. The clipboard events are defined in ourClipboardEventProps
, we do not have touch events.
Maybe, we can also make it more clear somehow, which EventProps
traits belong to which EventTarget
?
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.
I will update the comments
|
||
/** | ||
* The click event is raised when the user clicks on an element. The click | ||
* event will occur after the mousedown and mouseup events. | ||
* | ||
* MDN | ||
*/ | ||
lazy val onClick: EP[DomMouseEvent] = eventProp("click") | ||
lazy val onClick: EP[DomMouseEvent with DomHtmlElementTargetEvent] = eventProp("click") |
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.
I suspect we can indeed do this, but is there any formal indication that such events will only happen on elements and not e.g. text nodes or SVG elements?
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.
Good catch, i think you are right! MDN actually only says the target type is Element
.
Then, I was probably also wrong to make onBlur
and onFocus
in FormEventProps
be an HTMLElementTargetEvent
, as they are also only defined for target Element
. Right?
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.
Yeah I think we should start out being somewhat conservative in this kind of thing, I'd be happy with dom.Element
where MDN says so. If we start relying on "conveniently incorrect" types the eventual withdrawal will be painful... I'm still hoping that the other approach I mentioned in a comment on this issue in outwatch will work better for this.
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.
Sounds right, I will update those event props to having target of type dom.Element
. We can always revisit if there is new information.
9d0149a
to
6d9f28d
Compare
@@ -6,6 +6,6 @@ import scala.scalajs.js | |||
|
|||
/** Represents an event for which we know what exact type the `target` is. */ | |||
@js.native | |||
trait ElementTargetEvent[+E <: dom.html.Element] extends dom.Event { | |||
trait TypedTargetEvent[+E <: dom.EventTarget] extends dom.Event { |
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.
👍
|
||
/** | ||
* The click event is raised when the user clicks on an element. The click | ||
* event will occur after the mousedown and mouseup events. | ||
* | ||
* MDN | ||
*/ | ||
lazy val onClick: EP[DomMouseEvent] = eventProp("click") | ||
lazy val onClick: EP[DomMouseEvent with DomHtmlElementTargetEvent] = eventProp("click") |
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.
Yeah I think we should start out being somewhat conservative in this kind of thing, I'd be happy with dom.Element
where MDN says so. If we start relying on "conveniently incorrect" types the eventual withdrawal will be painful... I'm still hoping that the other approach I mentioned in a comment on this issue in outwatch will work better for this.
trait EventPropsInWindow[EP[_ <: dom.Event]] extends EventPropsInGlobal[EP] with WindowEventProps[EP] { this: generic.builders.EventPropBuilder[EP, dom.Event] => } | ||
trait EventPropsInDocument[EP[_ <: dom.Event]] extends EventPropsInGlobal[EP] with ClipboardEventProps[EP] { this: generic.builders.EventPropBuilder[EP, dom.Event] => } | ||
trait EventPropsInElement[EP[_ <: dom.Event]] extends EventPropsInGlobal[EP] { this: generic.builders.EventPropBuilder[EP, dom.Event] => } | ||
trait EventPropsInHTMLElement[EP[_ <: dom.Event]] extends EventPropsInGlobal[EP] with ClipboardEventProps[EP] { this: generic.builders.EventPropBuilder[EP, dom.Event] => } |
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.
Hmm... I'm not sure if these new traits should reside in SDT. I don't really see a good way to use more than one of those traits at a time in a typical consuming library. I mean, the names would conflict, and you'd need to instantiate way more eventprop objects than needed... right? Maybe I'm missing something?
I'm guessing #13 is related here
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.
Actually, I would like sdt to bring those type as they tell me which event properties are applicable to which underlying EventTarget
type.
My plan is to have the following three usages:
trait DomEventProps extends EventPropsInHTMLElement[EmitterBuilder] with EventPropBuilder[EmitterBuilder, dom.Event]
for normal usage within tags as it is now, like:input(onChange --> sink)
.object WindowEvents extends EventPropsInWindow[Observable] with EventPropBuilder[Observable, dom.Event]
for registering window events via an observable:WindowEvents.onStorage.map(ev => ...)
.object DocumentEvents extends EventPropsInDocument[Observable] with EventPropBuilder[Observable, dom.Event]
for registering document events via an observable:DocumentEvents.onLoad.map(ev => ...)
.
The latter two can be build by creating an observable from the callback we have when registering an event with (Window|Document).attachEventListener(eventKey, callback)
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.
Oh that's a nice pattern! I myself was using node.events(onClick)
pattern because I don't want each node to extend a trait with a hundred vals, even if they're lazy. But for document / window this looks reasonable.
Let's keep all those traits then.
I'm assuming you named the new traits ...InX
as opposed to X...
because EventPropsInWindow
would otherwise conflict with WindowEventProps
? Should we maybe rename the original WindowEventProps
to WindowOnlyEventProps
or something like that? Would look nicer and would also sort of better match Javascript's stuff:
https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers
https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers
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.
Exactly! Sure, we can rename them; I wasn't too happy with this ...In...
:)
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.
node.events(onClick)
With regards to outwatch/outwatch#93, that approach would work much better with the currentTarget
-event.
@@ -19,7 +22,7 @@ import com.raquo.domtypes.generic.builders.EventPropBuilder | |||
* DOM InputEvent https://developer.mozilla.org/en-US/docs/Web/API/InputEvent | |||
* Note: This type is not implemented in scala-js-dom | |||
*/ | |||
trait FormEventProps[EP[_ <: DomEvent], DomEvent, DomFocusEvent <: DomEvent, DomInputEvent <: DomEvent, DomHtmlElementTargetEvent <: DomEvent, DomFormElementTargetEvent <: DomEvent, DomInputElementTargetEvent <: DomEvent] { this: EventPropBuilder[EP, DomEvent] => | |||
trait FormEventProps[EP[_ <: DomEvent], DomEvent, DomFocusEvent <: DomEvent, DomInputEvent <: DomEvent, DomElementTargetEvent <: DomEvent, DomHtmlElementTargetEvent <: DomEvent, DomFormElementTargetEvent <: DomEvent, DomInputElementTargetEvent <: DomEvent] { this: EventPropBuilder[EP, DomEvent] => |
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.
I am not completely sure about the target
types anymore. Why does MDN often say target: Element
, but then in the description gives a more concrete type on which elements the event can occur?
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.
Well, conventional JS ideology is largely "let's try to run this and see what we get", so I don't imagine JS devs care all that much about what types are specified. There are also potentially some differences in what is specified in the DOM standard and what is actually implemented in browsers, but I'd think those are minimal by now. I think it's mostly just that JS users largely don't care about minor typing details like this.
For the submit
event MDN says "Note that submit is fired only on the form element, not the button or submit input. (Forms are submitted, not buttons.)", and I've verified this behavior manually in a couple browsers, so I'm confident enough to put Form
as the type of target for such an event.
b748f95
to
acbdd54
Compare
- mouse events with element target - move onscroll to MiscellaneousEventProps (has no mouse event) - move onload and onresize to MiscellaneousEventProps (are global event handlers)
@cornerman Thanks for working on this! I've just released v0.4 |
Great! I think, it should be ready now for outwatch. Thank you so much for all your effort! |
No description provided.