Skip to content

Commit

Permalink
airframe-rx-html: Add type-safe event handler (#2044)
Browse files Browse the repository at this point in the history
  • Loading branch information
exoego committed Jan 31, 2022
1 parent 606b4c1 commit 9b23ccc
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 21 deletions.
Expand Up @@ -20,4 +20,7 @@ object compat {
trait PlatformEmbeddableNode {
@inline implicit def embedHtmlElement[A <: dom.Element]: EmbeddableNode[A] = null
}
type UIEvent = dom.UIEvent
type MouseEvent = dom.MouseEvent
type WheelEvent = dom.WheelEvent
}
Expand Up @@ -17,4 +17,7 @@ package wvlet.airframe.rx.html
*/
object compat {
trait PlatformEmbeddableNode {}
type UIEvent = org.w3c.dom.events.UIEvent
type MouseEvent = org.w3c.dom.events.MouseEvent
type WheelEvent = org.w3c.dom.events.UIEvent // WheelEvent not defined
}
32 changes: 16 additions & 16 deletions airframe-rx-html/src/main/scala/wvlet/airframe/rx/html/Attrs.scala
Expand Up @@ -527,98 +527,98 @@ trait MouseEventAttrs {
*
* MDN
*/
lazy val onclick = attr("onclick")
lazy val onclick = handler[compat.MouseEvent]("onclick")

/**
* The dblclick event is fired when a pointing device button (usually a mouse button) is clicked twice on a single
* element.
*
* MDN
*/
lazy val ondblclick = attr("ondblclick")
lazy val ondblclick = handler[compat.MouseEvent]("ondblclick")

/**
* Script to be run when an element is dragged
*/
val ondrag = attr("ondrag")
val ondrag = handler[compat.MouseEvent]("ondrag")

/**
* Script to be run at the end of a drag operation
*/
lazy val ondragend = attr("ondragend")
lazy val ondragend = handler[compat.MouseEvent]("ondragend")

/**
* Script to be run when an element has been dragged to a valid drop target
*/
lazy val ondragenter = attr("ondragenter")
lazy val ondragenter = handler[compat.MouseEvent]("ondragenter")

/**
* Script to be run when an element leaves a valid drop target
*/
lazy val ondragleave = attr("ondragleave")
lazy val ondragleave = handler[compat.MouseEvent]("ondragleave")

/**
* Script to be run when an element is being dragged over a valid drop target
*/
lazy val ondragover = attr("ondragover")
lazy val ondragover = handler[compat.MouseEvent]("ondragover")

/**
* Script to be run at the start of a drag operation
*/
lazy val ondragstart = attr("ondragstart")
lazy val ondragstart = handler[compat.MouseEvent]("ondragstart")

/**
* Script to be run when dragged element is being dropped
*/
lazy val ondrop = attr("ondrop")
lazy val ondrop = handler[compat.MouseEvent]("ondrop")

/**
* The mousedown event is raised when the user presses the mouse button.
*
* MDN
*/
lazy val onmousedown = attr("onmousedown")
lazy val onmousedown = handler[compat.MouseEvent]("onmousedown")

/**
* The mousemove event is raised when the user moves the mouse.
*
* MDN
*/
lazy val onmousemove = attr("onmousemove")
lazy val onmousemove = handler[compat.MouseEvent]("onmousemove")

/**
* The mouseout event is raised when the mouse leaves an element (e.g, when the mouse moves off of an image in the
* web page, the mouseout event is raised for that image element).
*
* MDN
*/
lazy val onmouseout = attr("onmouseout")
lazy val onmouseout = handler[compat.MouseEvent]("onmouseout")

/**
* The mouseover event is raised when the user moves the mouse over a particular element.
*
* MDN
*/
lazy val onmouseover = attr("onmouseover")
lazy val onmouseover = handler[compat.MouseEvent]("onmouseover")

/**
* The mouseup event is raised when the user releases the mouse button.
*
* MDN
*/
lazy val onmouseup = attr("onmouseup")
lazy val onmouseup = handler[compat.MouseEvent]("onmouseup")

/**
* Specifies the function to be called when the window is scrolled.
*
* MDN
*/
lazy val onscroll = attr("onscroll")
lazy val onscroll = handler[compat.UIEvent]("onscroll")

/**
* Fires when the mouse wheel rolls up or down over an element
*/
lazy val onwheel = attr("onwheel")
lazy val onwheel = handler[compat.WheelEvent]("onwheel")
}

/**
Expand Down
Expand Up @@ -59,6 +59,14 @@ package object html {
def noValue: HtmlNode = HtmlAttribute(name, true, namespace)
}

class HtmlEventHandlerOf[E](name: String, namespace: Namespace = Namespace.xhtml) {
def apply[U](v: E => U): HtmlNode = HtmlAttribute(name, v, namespace)
def ->[U](v: E => U): HtmlNode = apply(v)
def apply[U](v: () => U): HtmlNode = HtmlAttribute(name, v, namespace)
def ->[U](v: () => U): HtmlNode = apply(v)
def noValue: HtmlNode = HtmlAttribute(name, false, namespace)
}

case class EntityRef(ref: String) extends HtmlNode

// TODO embed namespace properly to DOM
Expand All @@ -70,11 +78,13 @@ package object html {
val svgXLink = Namespace("http://www.w3.org/1999/xlink")
}

def tag(name: String): HtmlElement = new HtmlElement(name)
def tagOf(name: String, namespace: Namespace) = new HtmlElement(name, namespace)
def attr(name: String): HtmlAttributeOf = new HtmlAttributeOf(name)
def attr(name: String, namespace: Namespace): HtmlAttributeOf = new HtmlAttributeOf(name, namespace)
def attributeOf(name: String): HtmlAttributeOf = attr(name)
def tag(name: String): HtmlElement = new HtmlElement(name)
def tagOf(name: String, namespace: Namespace) = new HtmlElement(name, namespace)
def attr(name: String): HtmlAttributeOf = new HtmlAttributeOf(name)
def attr(name: String, namespace: Namespace): HtmlAttributeOf = new HtmlAttributeOf(name, namespace)
def attributeOf(name: String): HtmlAttributeOf = attr(name)
def handler[T](name: String): HtmlEventHandlerOf[T] = new HtmlEventHandlerOf[T](name)
def handler[T](name: String, namespace: Namespace): HtmlEventHandlerOf[T] = new HtmlEventHandlerOf[T](name, namespace)

@implicitNotFound(msg = "Unsupported type as an attribute value")
trait EmbeddableAttribute[X]
Expand Down

0 comments on commit 9b23ccc

Please sign in to comment.