-
Notifications
You must be signed in to change notification settings - Fork 110
/
Framework.scala
52 lines (48 loc) · 1.63 KB
/
Framework.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package example
import scalatags.JsDom.all._
import scala.util.{Failure, Success}
import rx._
import org.scalajs.dom.{html, Element}
/**
* A minimal binding between Scala.Rx and Scalatags and Scala-Js-Dom
*/
object Framework {
/**
* Wraps reactive strings in spans, so they can be referenced/replaced
* when the Rx changes.
*/
implicit def RxStr[T](r: Rx[T])(implicit f: T => Frag, ctx: Ctx.Owner): Frag = {
rxMod(Rx(span(r())))
}
/**
* Sticks some Rx into a Scalatags fragment, which means hooking up an Obs
* to propagate changes into the DOM via the element's ID. Monkey-patches
* the Obs onto the element itself so we have a reference to kill it when
* the element leaves the DOM (e.g. it gets deleted).
*/
implicit def rxMod[T <: html.Element](r: Rx[HtmlTag])(implicit ctx: Ctx.Owner): Frag = {
def rSafe = r.toTry match {
case Success(v) => v.render
case Failure(e) => span(e.toString, backgroundColor := "red").render
}
var last = rSafe
r.trigger {
val newLast = rSafe
Option(last.parentElement).foreach {
_.replaceChild(newLast, last)
}
last = newLast
}
bindNode(last)
}
implicit def RxAttrValue[T: AttrValue](implicit ctx: Ctx.Owner) = new AttrValue[Rx.Dynamic[T]] {
def apply(t: Element, a: Attr, r: Rx.Dynamic[T]): Unit = {
r.trigger { implicitly[AttrValue[T]].apply(t, a, r.now) }
}
}
implicit def RxStyleValue[T: StyleValue](implicit ctx: Ctx.Owner) = new StyleValue[Rx.Dynamic[T]] {
def apply(t: Element, s: Style, r: Rx.Dynamic[T]): Unit = {
r.trigger { implicitly[StyleValue[T]].apply(t, s, r.now) }
}
}
}