Skip to content

Commit ec91f15

Browse files
authored
airframe-rx-html: Fix Rx node rendering (#912)
* airframe-rx-html: Fix Rx node rendering * airframe-rx-html: RxElement.add
1 parent 64fd0c9 commit ec91f15

File tree

5 files changed

+30
-12
lines changed

5 files changed

+30
-12
lines changed

airframe-rx-widget/src/main/scala/wvlet/airframe/rx/widget/ui/bootstrap/NavBar.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
package wvlet.airframe.rx.widget.ui.bootstrap
1515

1616
import wvlet.airframe.rx.html.all._
17-
import wvlet.airframe.rx.html.{RxElement, RxComponent}
17+
import wvlet.airframe.rx.html.{RxComponent, RxElement}
1818

1919
/**
2020
*
@@ -40,7 +40,8 @@ case class NavBar(title: String, iconFile: String = "img/favicon.ico", iconWidth
4040
aria.expanded -> "false",
4141
aria.label -> "Toggle navigation",
4242
span(cls -> "navbar-toggler-icon")
43-
) { content }
43+
),
44+
content
4445
)
4546
}
4647

airframe-rx-widget/src/test/scala/wvlet/airframe/rx/widget/RxWidgetTest.scala

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,10 @@ class RxWidgetTest extends AirSpec {
5858
}
5959

6060
test("render buttons with click action") {
61-
val elem = Button.primary("my button")(onclick { () =>
62-
debug("clicked")
63-
})
61+
val elem = Button
62+
.primary("my button").add(onclick { () =>
63+
debug("clicked")
64+
})
6465
val html = render(elem)
6566
html.contains("btn btn-primary") shouldBe true
6667
}
@@ -99,4 +100,17 @@ class RxWidgetTest extends AirSpec {
99100
node.innerHTML shouldBe """<div><ul><li>Home</li><li class="active">Blog</li></ul></div>"""
100101
}
101102

103+
case class Label(id: String, name: String)
104+
105+
test("Render Rx as top-level node") {
106+
val currentPage = Rx.variable("home")
107+
val d = currentPage.map { page =>
108+
p(s"page: ${page}")
109+
}
110+
111+
val node = dom.document.createElement("div")
112+
renderTo(node, d)
113+
node.innerHTML shouldBe "<p>page: home</p>"
114+
}
115+
102116
}

airframe-rx/.js/src/main/scala/wvlet/airframe/rx/html/DOMRenderer.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ object DOMRenderer extends LogSupport {
5757
case d: dom.Node =>
5858
(d, Cancelable.empty)
5959
case other =>
60-
throw new IllegalArgumentException(s"unsupported top level element: ${other}")
60+
throw new IllegalArgumentException(s"unsupported top level element: ${other}. Use renderTo")
6161
}
6262
}
6363
traverse(e)
6464
}
6565

6666
private def newTextNode(s: String): dom.Text = dom.document.createTextNode(s)
6767

68-
def renderTo(node: dom.Node, htmlNode: HtmlNode): Cancelable = {
68+
def renderTo(node: dom.Node, htmlNode: HtmlNode, modifier: dom.Node => dom.Node = identity): Cancelable = {
6969

7070
def traverse(v: Any, anchor: Option[dom.Node]): Cancelable = {
7171
v match {
@@ -95,8 +95,9 @@ object DOMRenderer extends LogSupport {
9595
case e: Embedded =>
9696
traverse(e.v, anchor)
9797
case rx: RxElement =>
98-
val (elem, c1) = render(rx.render)
99-
val c2 = rx.traverseModifiers(m => renderTo(elem, m))
98+
val c1 = renderTo(node, rx.render)
99+
val elem = node.lastChild
100+
val c2 = rx.traverseModifiers(m => renderTo(elem, m))
100101
node.mountHere(elem, anchor)
101102
Cancelable.merge(c1, c2)
102103
case s: String =>

airframe-rx/src/main/scala/wvlet/airframe/rx/html/RxElement.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ abstract class RxElement(val modifiers: List[Seq[HtmlNode]] = List.empty) extend
3535
}
3636
}
3737

38-
def addModifier(xs: HtmlNode*): RxElement = new RxElement(xs :: modifiers) {
38+
def add(xs: HtmlNode*): RxElement = new RxElement(xs :: modifiers) {
3939
override def render = self.render
4040
}
41+
def addModifier(xs: HtmlNode*): RxElement = add(xs: _*)
4142

4243
private[html] def traverseModifiers(f: HtmlNode => Cancelable): Cancelable = {
4344
val cancelables = for (g <- modifiers.reverse; m <- g) yield {

airframe-rx/src/main/scala/wvlet/airframe/rx/html/package.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ package object html {
5353

5454
class HtmlAttributeOf(name: String, namespace: Namespace = Namespace.xhtml) {
5555
def apply[V: EmbeddableAttribute](v: V): HtmlNode = HtmlAttribute(name, v, namespace)
56-
def ->[V: EmbeddableAttribute](v: V): HtmlNode = HtmlAttribute(name, v, namespace)
57-
def +=[V: EmbeddableAttribute](v: V): HtmlNode = HtmlAttribute(name, v, namespace, append = true)
56+
def ->[V: EmbeddableAttribute](v: V): HtmlNode = apply(v)
57+
def add[V: EmbeddableAttribute](v: V): HtmlNode = HtmlAttribute(name, v, namespace, append = true)
58+
def +=[V: EmbeddableAttribute](v: V): HtmlNode = add(v)
5859
def noValue: HtmlNode = HtmlAttribute(name, true, namespace)
5960
}
6061

0 commit comments

Comments
 (0)