From b0551c930f1a132a70f4897cf375b7e36e5f08c2 Mon Sep 17 00:00:00 2001
From: Tobias Schlatter <tobias@meisch.ch>
Date: Thu, 12 Jun 2014 15:40:22 +0200
Subject: [PATCH 1/7] Step 1: Setup

---
 build.sbt                                        | 7 +++++++
 project/build.properties                         | 1 +
 project/plugins.sbt                              | 1 +
 src/main/scala/tutorial/webapp/TutorialApp.scala | 7 +++++++
 4 files changed, 16 insertions(+)
 create mode 100644 build.sbt
 create mode 100644 project/build.properties
 create mode 100644 project/plugins.sbt
 create mode 100644 src/main/scala/tutorial/webapp/TutorialApp.scala

diff --git a/build.sbt b/build.sbt
new file mode 100644
index 0000000..127dc4d
--- /dev/null
+++ b/build.sbt
@@ -0,0 +1,7 @@
+enablePlugins(ScalaJSPlugin)
+
+name := "Scala.js Tutorial"
+scalaVersion := "3.3.3"
+
+// This is an application with a main method
+scalaJSUseMainModuleInitializer := true
diff --git a/project/build.properties b/project/build.properties
new file mode 100644
index 0000000..04267b1
--- /dev/null
+++ b/project/build.properties
@@ -0,0 +1 @@
+sbt.version=1.9.9
diff --git a/project/plugins.sbt b/project/plugins.sbt
new file mode 100644
index 0000000..e5b2699
--- /dev/null
+++ b/project/plugins.sbt
@@ -0,0 +1 @@
+addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0")
diff --git a/src/main/scala/tutorial/webapp/TutorialApp.scala b/src/main/scala/tutorial/webapp/TutorialApp.scala
new file mode 100644
index 0000000..9be2dd8
--- /dev/null
+++ b/src/main/scala/tutorial/webapp/TutorialApp.scala
@@ -0,0 +1,7 @@
+package tutorial.webapp
+
+object TutorialApp {
+  def main(args: Array[String]): Unit = {
+    println("Hello world!")
+  }
+}

From 019dd65578cbc7c61cf9f16080a06c36b2916469 Mon Sep 17 00:00:00 2001
From: Tobias Schlatter <tobias@meisch.ch>
Date: Fri, 13 Jun 2014 08:58:35 +0200
Subject: [PATCH 2/7] Step 2: Integrating with HTML

---
 scalajs-tutorial-fastopt.html | 11 +++++++++++
 1 file changed, 11 insertions(+)
 create mode 100644 scalajs-tutorial-fastopt.html

diff --git a/scalajs-tutorial-fastopt.html b/scalajs-tutorial-fastopt.html
new file mode 100644
index 0000000..b28d999
--- /dev/null
+++ b/scalajs-tutorial-fastopt.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="UTF-8">
+    <title>The Scala.js Tutorial</title>
+  </head>
+  <body>
+    <!-- Include Scala.js compiled code -->
+    <script type="text/javascript" src="./target/scala-2.13/scala-js-tutorial-fastopt/main.js"></script>
+  </body>
+</html>

From 322e73559401c8c6c671887a1e9f890b7d281e70 Mon Sep 17 00:00:00 2001
From: Tobias Schlatter <tobias@meisch.ch>
Date: Fri, 13 Jun 2014 10:42:28 +0200
Subject: [PATCH 3/7] Step 3: Using the DOM

---
 build.sbt                                        |  2 ++
 src/main/scala/tutorial/webapp/TutorialApp.scala | 11 ++++++++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/build.sbt b/build.sbt
index 127dc4d..2c35856 100644
--- a/build.sbt
+++ b/build.sbt
@@ -5,3 +5,5 @@ scalaVersion := "3.3.3"
 
 // This is an application with a main method
 scalaJSUseMainModuleInitializer := true
+
+libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "2.8.0"
diff --git a/src/main/scala/tutorial/webapp/TutorialApp.scala b/src/main/scala/tutorial/webapp/TutorialApp.scala
index 9be2dd8..5c64096 100644
--- a/src/main/scala/tutorial/webapp/TutorialApp.scala
+++ b/src/main/scala/tutorial/webapp/TutorialApp.scala
@@ -1,7 +1,16 @@
 package tutorial.webapp
 
+import org.scalajs.dom
+import org.scalajs.dom.document
+
 object TutorialApp {
   def main(args: Array[String]): Unit = {
-    println("Hello world!")
+    appendPar(document.body, "Hello World")
+  }
+
+  def appendPar(targetNode: dom.Node, text: String): Unit = {
+    val parNode = document.createElement("p")
+    parNode.textContent = text
+    targetNode.appendChild(parNode)
   }
 }

From d2adbfeb036400b7cd5b45ff33e7aeedc34821ab Mon Sep 17 00:00:00 2001
From: Tobias Schlatter <tobias@meisch.ch>
Date: Fri, 13 Jun 2014 10:57:20 +0200
Subject: [PATCH 4/7] Step 4: Reacting on User Input

---
 scalajs-tutorial-fastopt.html                    | 4 ++++
 src/main/scala/tutorial/webapp/TutorialApp.scala | 7 +++++++
 2 files changed, 11 insertions(+)

diff --git a/scalajs-tutorial-fastopt.html b/scalajs-tutorial-fastopt.html
index b28d999..213b913 100644
--- a/scalajs-tutorial-fastopt.html
+++ b/scalajs-tutorial-fastopt.html
@@ -5,6 +5,10 @@
     <title>The Scala.js Tutorial</title>
   </head>
   <body>
+    <button id="click-me-button" type="button" onclick="addClickedMessage()">
+      Click me!
+    </button>
+
     <!-- Include Scala.js compiled code -->
     <script type="text/javascript" src="./target/scala-2.13/scala-js-tutorial-fastopt/main.js"></script>
   </body>
diff --git a/src/main/scala/tutorial/webapp/TutorialApp.scala b/src/main/scala/tutorial/webapp/TutorialApp.scala
index 5c64096..e3ba9dc 100644
--- a/src/main/scala/tutorial/webapp/TutorialApp.scala
+++ b/src/main/scala/tutorial/webapp/TutorialApp.scala
@@ -1,5 +1,7 @@
 package tutorial.webapp
 
+import scala.scalajs.js.annotation.JSExportTopLevel
+
 import org.scalajs.dom
 import org.scalajs.dom.document
 
@@ -13,4 +15,9 @@ object TutorialApp {
     parNode.textContent = text
     targetNode.appendChild(parNode)
   }
+
+  @JSExportTopLevel("addClickedMessage")
+  def addClickedMessage(): Unit = {
+    appendPar(document.body, "You clicked the button!")
+  }
 }

From 66cb9a642f58aecd2ca1fcff8c138e840d5c7f73 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= <sjrdoeraene@gmail.com>
Date: Sat, 23 Jan 2016 11:10:26 +0100
Subject: [PATCH 5/7] Step 5: Setup the UI in Scala.js

---
 scalajs-tutorial-fastopt.html                    |  4 ----
 src/main/scala/tutorial/webapp/TutorialApp.scala | 16 +++++++++++++---
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/scalajs-tutorial-fastopt.html b/scalajs-tutorial-fastopt.html
index 213b913..b28d999 100644
--- a/scalajs-tutorial-fastopt.html
+++ b/scalajs-tutorial-fastopt.html
@@ -5,10 +5,6 @@
     <title>The Scala.js Tutorial</title>
   </head>
   <body>
-    <button id="click-me-button" type="button" onclick="addClickedMessage()">
-      Click me!
-    </button>
-
     <!-- Include Scala.js compiled code -->
     <script type="text/javascript" src="./target/scala-2.13/scala-js-tutorial-fastopt/main.js"></script>
   </body>
diff --git a/src/main/scala/tutorial/webapp/TutorialApp.scala b/src/main/scala/tutorial/webapp/TutorialApp.scala
index e3ba9dc..ac34cfd 100644
--- a/src/main/scala/tutorial/webapp/TutorialApp.scala
+++ b/src/main/scala/tutorial/webapp/TutorialApp.scala
@@ -1,12 +1,23 @@
 package tutorial.webapp
 
-import scala.scalajs.js.annotation.JSExportTopLevel
-
 import org.scalajs.dom
 import org.scalajs.dom.document
 
 object TutorialApp {
   def main(args: Array[String]): Unit = {
+    document.addEventListener("DOMContentLoaded", { (e: dom.Event) =>
+      setupUI()
+    })
+  }
+
+  def setupUI(): Unit = {
+    val button = document.createElement("button")
+    button.textContent = "Click me!"
+    button.addEventListener("click", { (e: dom.MouseEvent) =>
+      addClickedMessage()
+    })
+    document.body.appendChild(button)
+
     appendPar(document.body, "Hello World")
   }
 
@@ -16,7 +27,6 @@ object TutorialApp {
     targetNode.appendChild(parNode)
   }
 
-  @JSExportTopLevel("addClickedMessage")
   def addClickedMessage(): Unit = {
     appendPar(document.body, "You clicked the button!")
   }

From ece173574f17047718e0636e853b9c0da1492572 Mon Sep 17 00:00:00 2001
From: Tobias Schlatter <tobias@meisch.ch>
Date: Sat, 14 Jun 2014 16:18:27 +0200
Subject: [PATCH 6/7] Step 6: Testing

---
 build.sbt                                     |  7 ++++
 project/plugins.sbt                           |  2 ++
 .../scala/tutorial/webapp/TutorialTest.scala  | 35 +++++++++++++++++++
 3 files changed, 44 insertions(+)
 create mode 100644 src/test/scala/tutorial/webapp/TutorialTest.scala

diff --git a/build.sbt b/build.sbt
index 2c35856..0153d1d 100644
--- a/build.sbt
+++ b/build.sbt
@@ -7,3 +7,10 @@ scalaVersion := "3.3.3"
 scalaJSUseMainModuleInitializer := true
 
 libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "2.8.0"
+
+// Add support for the DOM in `run` and `test`
+jsEnv := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv()
+
+// uTest settings
+libraryDependencies += "com.lihaoyi" %%% "utest" % "0.8.2" % "test"
+testFrameworks += new TestFramework("utest.runner.Framework")
diff --git a/project/plugins.sbt b/project/plugins.sbt
index e5b2699..6df9fb3 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -1 +1,3 @@
 addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0")
+
+libraryDependencies += "org.scala-js" %% "scalajs-env-jsdom-nodejs" % "1.1.0"
diff --git a/src/test/scala/tutorial/webapp/TutorialTest.scala b/src/test/scala/tutorial/webapp/TutorialTest.scala
new file mode 100644
index 0000000..47503fc
--- /dev/null
+++ b/src/test/scala/tutorial/webapp/TutorialTest.scala
@@ -0,0 +1,35 @@
+package tutorial.webapp
+
+import utest._
+
+import scala.scalajs.js
+
+import org.scalajs.dom
+import org.scalajs.dom.document
+import org.scalajs.dom.ext._
+
+object TutorialTest extends TestSuite {
+
+  // Initialize App
+  TutorialApp.setupUI()
+
+  def tests = Tests {
+    test("HelloWorld") {
+      assert(document.querySelectorAll("p").count(_.textContent == "Hello World") == 1)
+    }
+
+    test("ButtonClick") {
+      def messageCount =
+        document.querySelectorAll("p").count(_.textContent == "You clicked the button!")
+
+      val button = document.querySelector("button").asInstanceOf[dom.html.Button]
+      assert(button != null && button.textContent == "Click me!")
+      assert(messageCount == 0)
+
+      for (c <- 1 to 5) {
+        button.click()
+        assert(messageCount == c)
+      }
+    }
+  }
+}

From 65fe0b655791fd4a6786948fe98658a2953447e6 Mon Sep 17 00:00:00 2001
From: Tobias Schlatter <tobias@meisch.ch>
Date: Fri, 13 Jun 2014 17:00:28 +0200
Subject: [PATCH 7/7] Step 7: Optimizing for Production

---
 scalajs-tutorial.html | 11 +++++++++++
 1 file changed, 11 insertions(+)
 create mode 100644 scalajs-tutorial.html

diff --git a/scalajs-tutorial.html b/scalajs-tutorial.html
new file mode 100644
index 0000000..90f0879
--- /dev/null
+++ b/scalajs-tutorial.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="UTF-8">
+    <title>The Scala.js Tutorial</title>
+  </head>
+  <body>
+    <!-- Include Scala.js compiled code -->
+    <script type="text/javascript" src="./target/scala-2.13/scala-js-tutorial-opt/main.js"></script>
+  </body>
+</html>