Skip to content

Commit

Permalink
Fix issue where className attribute wasn't rendered correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
shogowada committed Apr 5, 2017
1 parent a4010b7 commit c330b23
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 17 deletions.
16 changes: 14 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ val ReactReduxVersion = "^5.0.3"
val ReactRouterVersion = "^3.0.0"
val ReduxVersion = "^3.6.0"

val StaticTagsVersion = "[2.2.0,3.0.0["

crossScalaVersions := Seq("2.11.8", "2.12.1")

publishTo := {
Expand All @@ -18,7 +20,7 @@ publishArtifact := false
val commonSettings = Seq(
organization := "io.github.shogowada",
name := "scalajs-reactjs",
version := "0.6.4-SNAPSHOT",
version := "0.6.4",
licenses := Seq("MIT" -> url("https://opensource.org/licenses/MIT")),
homepage := Some(url("https://github.com/shogowada/scalajs-reactjs")),
scalaVersion := "2.12.1",
Expand Down Expand Up @@ -52,7 +54,7 @@ lazy val core = project.in(file("core"))
.settings(
libraryDependencies ++= Seq(
"org.scala-js" %%% "scalajs-dom" % "0.9.+",
"io.github.shogowada" %%% "statictags" % "2.1.0"
"io.github.shogowada" %%% "statictags" % StaticTagsVersion
),
npmDependencies in Compile ++= Seq(
"fbjs" -> FbJsVersion,
Expand Down Expand Up @@ -139,6 +141,14 @@ lazy val exampleRouting = project.in(file("example") / "routing")
.enablePlugins(ScalaJSPlugin, ScalaJSBundlerPlugin)
.dependsOn(core, router)

lazy val exampleStyle = project.in(file("example") / "style")
.settings(exampleCommonSettings: _*)
.settings(
name += "-style"
)
.enablePlugins(ScalaJSPlugin, ScalaJSBundlerPlugin)
.dependsOn(core)

lazy val exampleTodoApp = project.in(file("example") / "todo-app")
.settings(exampleCommonSettings: _*)
.settings(
Expand Down Expand Up @@ -182,6 +192,7 @@ lazy val exampleTest = project.in(file("example") / "test")
s"-Dtarget.path.interactive-helloworld=${(crossTarget in exampleInteractiveHelloWorld).value}",
s"-Dtarget.path.lifecycle=${(crossTarget in exampleLifecycle).value}",
s"-Dtarget.path.routing=${(crossTarget in exampleRouting).value}",
s"-Dtarget.path.style=${(crossTarget in exampleStyle).value}",
s"-Dtarget.path.todo-app=${(crossTarget in exampleTodoApp).value}",
s"-Dtarget.path.todo-app-redux=${(crossTarget in exampleTodoAppRedux).value}",
s"-Ddummy.custom-virtual-dom=${(webpack in fastOptJS in Compile in exampleCustomVirtualDOM).value}",
Expand All @@ -190,6 +201,7 @@ lazy val exampleTest = project.in(file("example") / "test")
s"-Ddummy.interactive-helloworld=${(webpack in fastOptJS in Compile in exampleInteractiveHelloWorld).value}",
s"-Ddummy.lifecycle=${(webpack in fastOptJS in Compile in exampleLifecycle).value}",
s"-Ddummy.routing=${(webpack in fastOptJS in Compile in exampleRouting).value}",
s"-Ddummy.style=${(webpack in fastOptJS in Compile in exampleStyle).value}",
s"-Ddummy.todo-app=${(webpack in fastOptJS in Compile in exampleTodoApp).value}",
s"-Ddummy.todo-app-redux=${(webpack in fastOptJS in Compile in exampleTodoAppRedux).value}"
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,41 +240,37 @@ trait VirtualDOM extends StaticTags {
}
}

implicit def elementsToVirtualDoms(element: Element): ReactElement = {
implicit def elementsToVirtualDoms(element: Element): ReactElement =
React.createElement(
element.name,
attributesToReactAttributes(element.flattenedAttributes),
elementsToReactElements(element.flattenedContents): _*
)
}

private def attributesToReactAttributes(attributes: Iterable[Attribute[_]]): js.Dictionary[js.Any] = {
private def attributesToReactAttributes(attributes: Iterable[Attribute[_]]): js.Dictionary[js.Any] =
attributes
.map(attributeToReactAttribute)
.toMap
.toJSDictionary
}

private def attributeToReactAttribute(attribute: Attribute[_]): (String, js.Any) = {
private def attributeToReactAttribute(attribute: Attribute[_]): (String, js.Any) =
VirtualDOMAttributes.toReactAttributeName(attribute.name) -> attributeValueToReactAttributeValue(attribute)
}

private def attributeValueToReactAttributeValue(attribute: Attribute[_]): js.Any = {
attribute.value match {
case value: Map[String, _] => value.toJSDictionary
case _ => attribute.value.asInstanceOf[js.Any]
private def attributeValueToReactAttributeValue(attribute: Attribute[_]): js.Any =
attribute match {
case Attribute(_, value, AttributeValueType.CSS) => value.asInstanceOf[Map[String, _]].toJSDictionary
case Attribute(_, value, _) if js.typeOf(value.asInstanceOf[js.Any]) == "function" => value.asInstanceOf[js.Any]
value.asInstanceOf[js.Any]
case _ => attribute.valueToString
}
}

def elementsToReactElements(contents: Seq[Any]): Seq[js.Any] = {
def elementsToReactElements(contents: Seq[Any]): Seq[js.Any] =
contents.map(elementToReactElement)
}

private def elementToReactElement(content: Any): js.Any = {
private def elementToReactElement(content: Any): js.Any =
content match {
case element@Element(_, _, _, _) => elementsToVirtualDoms(element)
case spec: ReactClassSpec[_, _] => React.createElement(spec)
case _ => content.asInstanceOf[js.Any]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.github.shogowada.scalajs.reactjs.example.style

import io.github.shogowada.scalajs.reactjs.ReactDOM
import io.github.shogowada.scalajs.reactjs.VirtualDOM._
import io.github.shogowada.scalajs.reactjs.elements.ReactElement
import org.scalajs.dom

import scala.scalajs.js.JSApp

object Main extends JSApp {
override def main(): Unit = {
val mountNode = dom.document.createElement("div")
dom.document.body.appendChild(mountNode)
ReactDOM.render(Main(), mountNode)
}

def apply(): ReactElement = <.div()(
<.div(^.id := "green-text", ^.className := Seq("green"))("Green text!"),
<.div(^.id := "blue-big-text", ^.className := Seq("blue", "big"))("Blue big text!"),
<.div(^.id := "red-text", ^.style := Map("color" -> "red"))("Red text!")
)
}
18 changes: 18 additions & 0 deletions example/style/src/main/webapp/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<html>
<head>
<style>
.green {
color: green;
}
.blue {
color: blue;
}
.big {
font-size: 32pt;
}
</style>
</head>
<body>
<script src="../scalajs-bundler/main/scalajs-reactjs-example-style-fastopt-bundle.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ object TestTargetServers {
val interactiveHelloWorld = new TestTargetServer("interactive-helloworld")
val lifecycle = new TestTargetServer("lifecycle")
val routing = new TestTargetServer("routing")
val style = new TestTargetServer("style")
val todoApp = new TestTargetServer("todo-app")
val todoAppRedux = new TestTargetServer("todo-app-redux")

Expand All @@ -62,6 +63,7 @@ object TestTargetServers {
interactiveHelloWorld.start()
lifecycle.start()
routing.start()
style.start()
todoApp.start()
todoAppRedux.start()

Expand All @@ -72,6 +74,7 @@ object TestTargetServers {
interactiveHelloWorld.stop()
lifecycle.stop()
routing.stop()
style.stop()
todoApp.stop()
todoAppRedux.stop()
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.github.shogowada.scalajs.reactjs.example.style

import io.github.shogowada.scalajs.reactjs.example.TestTargetServers
import org.scalatest.concurrent.Eventually
import org.scalatest.selenium.Firefox
import org.scalatest.{Matchers, path}

class StyleTest extends path.FreeSpec
with Matchers
with Eventually
with Firefox {

val server = TestTargetServers.style

"given I am on the page" - {
go to server.host

"then it should show green text" in {
find(id("green-text")).flatMap(_.attribute("class")) should equal(Option("green"))
}

"then it should show blue big text" in {
find(id("blue-big-text")).flatMap(_.attribute("class")) should equal(Option("blue big"))
}

"then it should show red text" in {
find(id("red-text")).flatMap(_.attribute("style")) should equal(Option("color: red;"))
}
}

close()
}

0 comments on commit c330b23

Please sign in to comment.