summaryrefslogtreecommitdiff
path: root/book
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2014-11-01 00:56:30 -0700
committerLi Haoyi <haoyi@dropbox.com>2014-11-01 00:56:30 -0700
commitaae594fd3c8397abca4cd4e55f538d41b172b4e3 (patch)
treecef34e2404599a8547d864f3d5c158b5297783f0 /book
parent3d73267c4b3ecf3cdca54ded8dfd8a2caeeb3ca9 (diff)
downloadhands-on-scala-js-aae594fd3c8397abca4cd4e55f538d41b172b4e3.tar.gz
hands-on-scala-js-aae594fd3c8397abca4cd4e55f538d41b172b4e3.tar.bz2
hands-on-scala-js-aae594fd3c8397abca4cd4e55f538d41b172b4e3.zip
added everything
Diffstat (limited to 'book')
-rw-r--r--book/src/main/scalatex/book/CanvasApp.scalatex213
-rw-r--r--book/src/main/scalatex/book/GettingStarted.scalatex324
-rw-r--r--book/src/main/scalatex/book/Index.scalatex30
-rw-r--r--book/src/main/scalatex/book/Intro.scalatex189
-rw-r--r--book/src/main/scalatex/book/WebPage.scalatex132
5 files changed, 888 insertions, 0 deletions
diff --git a/book/src/main/scalatex/book/CanvasApp.scalatex b/book/src/main/scalatex/book/CanvasApp.scalatex
new file mode 100644
index 0000000..bdfa51a
--- /dev/null
+++ b/book/src/main/scalatex/book/CanvasApp.scalatex
@@ -0,0 +1,213 @@
+
+@p
+ By this point, you've already cloned and got your hands dirty fiddling around with the toy @a("workbench-example-app", href:="https://github.com/lihaoyi/workbench-example-app"). You have your editor set up, SBT installed, and have published the example application in a way you can host online for other people to see. Maybe you've even made some changes to the application to see what happens. Hopefully you're curious, and want to learn more.
+
+@p
+ In this section of the book, we will walk through making a small canvas application. This will expose you to important concepts like:
+
+@ul
+ @li
+ Taking input with Javascript event handlers
+ @li
+ Writing your application logic in Scala
+ @li
+ Using a timer to drive periodic actions
+
+@p
+ In general, while the previous chapter was mostly set-up and exploring the Scala.js project, this chapter will walk you through actually writing a non-trivial, self-contained Scala.js application. Throughout this chapter, we will only be making modifications to @code{ScalaJSExample.scala}; the rest of the project will remain unchanged.
+
+@sect{Making a Sketchpad using Mouse Input}
+
+ @p
+ To begin with, lets remove all the existing stuff in our @code{.scala} file and leave only the @hl.scala{object} and the @hl.scala{main} method. Let's start off with some necessary boilerplate:
+
+ @hl.ref("examples/src/main/scala/canvasapp/ScratchPad.scala", "/*setup*/", end = "/*code*/")
+
+ @p
+ As described earlier, this code uses the @hl.javascript{document.getElementById} function to fish out the @code{canvas} element that we interested in from the DOM. It then gets a rendering context from that @code{canvas}, and sets the height and width of the canvas to completely fill its containing element. Lastly, it fills out the canvas light-gray, so that we can see it on the page.
+
+ @p
+ Next, let's set some event handlers on the canvas:
+
+ @div(cls:="pure-g")
+ @div(cls:="pure-u-1 pure-u-md-13-24")
+ @hl.ref("examples/src/main/scala/canvasapp/ScratchPad.scala", "/*code*/")
+
+ @div(cls:="pure-u-1 pure-u-md-11-24")
+ @canvas(id:="canvas2", display:="block")
+ @script("ScratchPad().main(document.getElementById('canvas2'))")
+
+ @p
+ This code sets up the @code{mousedown} and @code{mouseup} events to keep track of whether or not the mouse has currently been clicked. It then draws black squares any time you move the mouse while the button is down. This lets you basically click-and-drag to draw pictures on the canvas. Try it out!
+
+ @p
+ In general, you have access to all the DOM APIs through the @hl.scala{dom} package as well as through Javascript objects such as the @hl.scala{dom.HTMLCanvasElement}. Setting the @code{onmouseXXX} callbacks is just one way of interacting with the DOM. With Scala.js, you also get a very handy autocomplete in the editor, which you can use to browse the various other APIs that are available for use:
+
+ @img(src:="images/Dropdown.png", maxWidth:="100%")
+
+ @p
+ Apart from mouse events, keyboard events, scroll events, input events, etc. are all usable from Scala.js as you'd expect
+
+@sect{Making a Clock using setInterval}
+
+ @p
+ You've already seen this in the previous example, but @hl.scala{dom.setInterval} can be used to schedule recurring, periodic events in your program. Common use cases include running the event loop for a game, making smooth animations, and other tasks of that sort which require some work to happen over a period of time.
+
+ @p
+ Again, we need roughly the same boilerplate as just now to set up the canvas:
+
+ @hl.ref("examples/src/main/scala/canvasapp/Clock.scala", "/*setup*/", "/*code*/")
+
+ @p
+ The only thing unusual here is that I'm going to create a @hl.scala{linearGradient} in order to make the stopwatch look pretty. This is by no means necessary, and you could simply make the @hl.scala{fillStyle} @hl.scala{"black"} if you want to keep things simple.
+
+ @p
+ Once that's done, it's only a few lines of code to set up a nice, live clock:
+
+ @div(cls:="pure-g")
+ @div(cls:="pure-u-1 pure-u-md-13-24")
+ @hl.ref("examples/src/main/scala/canvasapp/Clock.scala", "/*code*/")
+
+ @div(cls:="pure-u-1 pure-u-md-11-24")
+ @canvas(id:="canvas3", display:="block")
+ @script("Clock().main(document.getElementById('canvas3'))")
+
+ @p
+ As you can see, we're using more @a("Canvas APIs", href:="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D"), in this case dealing with rendering text on the canvas. Another thing we're using is the Javascript @a("Date", href:="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date") class, in Scala.js under the fully name @hl.scala{scala.scalajs.js.Date}, here imported as @hl.scala{js.Date}.
+
+@sect{Tying it together: Flappy Box}
+
+ @p
+ You've just seen two examples of how to use Scala.js, together with the Javascript DOM APIs, to make simple applications. However, we've only used the "Scala" in Scala.js in the most rudimentary fashion: setting a few primitives here and there, defining some methods, mainly just gluing together a few Javascript APIs
+
+ @p
+ In this example we will make a spiritual clone of the popular @a("Flappy Bird", href:="http://en.wikipedia.org/wiki/Flappy_Bird") video game. This game involves a few simple rules
+
+ @ul
+ @li
+ Your character starts in the middle of the screen
+ @li
+ Gravity pulls your character down
+ @li
+ Clicking/tapping the screen makes your character jump up
+ @li
+ There are obstacles that approach your character from the right side of the screen, and you have to make sure you go through the hole in each obstacle to avoid hitting it
+ @li
+ Don't go out of bounds!
+
+ @p
+ It's a relatively simple game, but there should be enough "business logic" in here that we won't be simply gluing together APIs. Let's start!
+
+ @sect{Setting Up the Canvas}
+ @hl.ref("examples/src/main/scala/canvasapp/FlappyLine.scala", "/*setup*/", end="/*variables*/")
+
+ @p
+ This section of the code is peripherally necessary, but not core to the implementation or logic of Flappy Box. We see the same @hl.scala{canvas}/@hl.scala{renderer} logic we've seen in all our examples, along with some logic to make the canvas a reasonable size, and some configuration of how we will render text to the canvas.
+
+ @p
+ In general, code like this will usually end up being necessary in a Scala.js program: the Javascript APIs that the browser provides to do things often ends up being somewhat roundabout and verbose. It's somewhat annoying to have to do for a small program such as this one, but in a larger application, the cost is both spread out over thousands of lines of code and also typically hidden away in some helpers, so you don't have to mess with this stuff unless you really want to.
+
+ @sect{Defining our State}
+ @hl.ref("examples/src/main/scala/canvasapp/FlappyLine.scala", "/*variables*/", end="def runDead")
+
+ @p
+ This is where we start defining things that are relevant to Flappy Box. There are roughly two groups of values here: immutable constants in the top group, and mutable variables in the bottom. The rough meaning of each variable is documented in the comments, and we'll see exactly how we use them later.
+
+ @p
+ One notable thing is that we're using a @hl.scala{collection.mutable.Queue} to store the list of obstacles. This is defined in the Scala standard library; in general, all the collections in the Scala standard library can be used without issue in Scala.js.
+
+ @sect{Game Logic}
+ @hl.ref("examples/src/main/scala/canvasapp/FlappyLine.scala", "def runLive", "def runDead")
+
+ @p
+ The @hl.scala{runLive} function is the meat of Flappy Box. In it, we
+
+ @ul
+ @li
+ Clear the canvas
+ @li
+ Generate new obstacles
+ @li
+ Apply velocity and acceleration to the player
+ @li
+ Check for collisions or out-of-bounds, killing the player if it happens
+ @li
+ Rendering everything, including the player as the namesake box
+
+ @p
+ This function basically contains all the game logic, from motion, to collision-detection, to rendering, so it's pretty large. Not that large though! And entirely understandable, even if it takes a few moments to read through.
+
+ @hl.ref("examples/src/main/scala/canvasapp/FlappyLine.scala", "def runDead", end="def run")
+
+ @p
+ This is the function that handles what happens when you're dead. Essentially, we reset all the mutable variables to their initial state, and just count down the @hl.scala{dead} counter until it reaches zero and we're considered alive again.
+
+ @sect{A Working Product}
+ @hl.ref("examples/src/main/scala/canvasapp/FlappyLine.scala", "def run")
+
+ @p
+ And finally, this is the code that kicks everything off: we define the @hl.scala{run} function to swap between @hl.scala{runLive} and @hl.scala{runDead}, register an @hl.scala{canvas.onclick} handler to make the player jump by tweaking his velocity, and we call @code{setInterval} to run the @hl.scala{run} function every 20 milliseconds.
+
+ @p
+ At almost 100 lines of code, this is quite a meaty example! Nonetheless, when all is said and done, you will find that the example actually works! Try it out!
+
+ @div
+ @canvas(id:="canvas4", display:="block")
+ @script("FlappyLine().main(document.getElementById('canvas4'))")
+
+@sect{Canvas Recap}
+ @p
+ We've now gone through the workings of building a handful of toy applications using Scala.js. What have we learnt in the process?
+
+ @sect{Development Speed}
+ @p
+ We've by now written a good chunk of Scala.js code, and perhaps debugged some mysterious errors, and tried some new things. One thing you've probably noticed is the efficiency of the process: you make a change in your editor, the browser reloads itself, and life goes on. There is a compile cycle, but after a few runs the compiler warms up and the compilation cycle drops to less than a second.
+ @p
+ Apart from the compilation/reload speed, you've probably noticed the benefit of tooling around Scala.js. Unlike Javascript editors, your existin Scala IDEs like IntelliJ or Eclipse can give very useful help when you're working with Scala.js. Autocomplete, error-highlghting, jump-to-definition, and a myriad other modern conveniences that are missing when working in dynamically-typed languages are present when working in Scala.js. This makes the code much less mysterious: you're no longer trying to guess what methods a value has, or what a method returns: it's all laid out in front of you in plain sight.
+
+ @sect{Full Scala}
+ @p
+ All of the examples so far have been very self-contained: they do not touch the HTML DOM, they do not make Ajax calls, or try to access web services. They don't push the limits of the browser's API.
+
+ @p
+ Nevertheless, these examples have exercised a good amount of the Scala language. List comprehensions, collections, the math library, and more. In general, most of the Scala standard library works under Scala.js, as well as a large number of third-party libraries. Unlike many other compile-to-Javascript languages out there, this isn't a language-that-looks-like-Scala: it is Scala through and through, with a tiny number of semantic differences.
+
+ @sect{Seamless Javascript Interop}
+ @p
+ Even if we take some time to read through the code we've written, it is not immediately obvious which bits of code are Scala and which bits are Javascript! It all kind of meshes together, for example if we take the Flappy Box source code:
+
+ @ul
+ @li
+ @hl.scala{obstacles} is a Scala @hl.scala{mutable.Queue}, as we defined it earlier, and all the methods on it are Scala method calls
+ @li
+ @hl.scala{renderer} is a Javascript @hl.javascript{CanvasRenderingContext2D}, and all the methods on it are Javascript method calls directly on the Javascript object
+ @li
+ @hl.scala{frame} is a Scala @hl.scala{Int}, and obeys Scala semantics, though it is implemented as a Javascript @hl.javascript{Number} under the hood.
+ @li
+ @hl.scala{playerY} and @hl.scala{playerV} are Scala @hl.scala{Double}s, implemented directly as Javascript @hl.javascript{Number}s
+
+ @p
+ This reveals something pretty interesting about Scala.js: even though Scala at-first-glance is a very different language from Javascript, the interoperation with Javascript is so seamless that you can't even tell from the code which values/methods are defined in Scala and which values/methods come from Javascript!
+ @p
+ These two classes of values/methods are treated very differently by the compiler when it comes to emitting the executable Javascript blob, but the compiler does not need extra syntax telling it which things belong to Scala and which to Javascript: the types are sufficient. @hl.scala{renderer}, for example is of type @hl.scala{dom.CanvasRenderContext2D} which is a subtype of @hl.scala{scalajs.js.Object}, indicating to the compiler that it needs special treatment. Primitives like @hl.scala{Double}s and @hl.scala{Int}s have similar treatment
+
+ @p
+ Overall, this seamless mix of Scala and Javascript values/methods/functions is a common theme in Scala.js applications, so you should expect to see more of it in later chapters of the book.
+
+ @hr
+
+ @p
+ You've now had some experience building small canvas applications in Scala.js. Why not try exercising your new-found skills? Here are some possibilities:
+
+ @ul
+ @li
+ Make more video games! I have a set of @a("retro-games ported to Scala.js", href:="http://lihaoyi.github.io/scala-js-games/"). Maybe re-make one of them without looking at the source, or maybe port some other game you're familiar with and enjoy playing. Even just drawing things on canvas, games can get @a("pretty elaborate", href:="http://lihaoyi.github.io/roll/").
+
+ @li
+ Explore the APIs! We've touched on a small number of Javascript APIs here, mainly for dealign with the canvas, but modern browsers offer a whole @a("zoo of functionality", href:="https://developer.mozilla.org/en-US/docs/Web/API"). Try making an application that uses @a("localStorage", href:="https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage") to save state even when you close the tab, or an application that works with the HTML DOM.
+
+ @li
+ Draw something pretty! We have a working canvas, a nice programming language, and a way to easily publish the results online. @a("Various", href:="http://www.scala-js-fiddle.com/gist/77a3840678d154257ca1/KochSnowflake.scala") @a("fractals", href:="http://www.scala-js-fiddle.com/gist/77a3840678d154257ca1/KochCurve.scala"), or @a("colorful visualizations", href:="http://www.scala-js-fiddle.com/gist/9443f8e0ecc68d1058ad/RayTracer.scala") are all possibilities.
+
+ @p
+ By this point you've some experience building stand-alone, single-canvas Scala.js applications, which has hopefully given you a feel for how Scala.js works. The problem is that few web applications satisfy the criteria of being stand-alone single-page canvas applications! Most web applications need to deal with the DOM of the HTML page, need to fetch data from web services, and generally need to do a lot of other messy things. We'll go into that in the next chapter
diff --git a/book/src/main/scalatex/book/GettingStarted.scalatex b/book/src/main/scalatex/book/GettingStarted.scalatex
new file mode 100644
index 0000000..ac484a8
--- /dev/null
+++ b/book/src/main/scalatex/book/GettingStarted.scalatex
@@ -0,0 +1,324 @@
+
+@p
+ To get started with Scala.js, you will need to prepare a few things:
+
+@ul
+ @li
+ @a("sbt", href:="http://www.scala-sbt.org/"): SBT is the most common build-tool in the Scala community, and is what we will use for building our Scala.js application. Their home page has a link to download and install it.
+ @li
+ An editor for Scala: @a("IntelliJ Scala", href:="http://blog.jetbrains.com/scala/") and @a("Eclipse ScalaIDE", href:="http://scala-ide.org/") are the most popular choices and work on all platforms, though there are others.
+ @li
+ @a("Git", href:="http://git-scm.com/"): This is a version-control system that we will use to download and manage our Scala.js projects.
+ @li
+ A terminal: on OSX you have @a("Terminal.app", href:="http://guides.macrumors.com/Terminal") already installed, in Linux you have @a("Terminal", href:="https://help.ubuntu.com/community/UsingTheTerminal"), and on Windows you have @a("PowerShell", href:="http://en.wikipedia.org/wiki/Windows_PowerShell").
+ @li
+ Your favorite web browser: @a("Chrome", href:="https://www.google.com/chrome") and @a("Firefox", href:="https://www.mozilla.org/en-US/firefox") are the most popular.
+
+@p
+ If you've worked with Scala before, you probably already have most of these installed. Otherwise, take a moment to download them before we get to work.
+
+@p
+ The quickest way to get started with Scala.js is to @code{git clone} @a("workbench-example-app", href:="https://github.com/lihaoyi/workbench-example-app"), go into the repository root, and run @code{~fastOptJS}
+
+@hl.bash
+ git clone https://github.com/lihaoyi/workbench-example-app
+ cd workbench-example-app
+ sbt ~fastOptJS
+
+@p
+ This should result in a bunch of spam to the console, and may take a few minutes the first time as SBT resolves and downloads all necessary dependencies. A successful run looks like this
+
+@pre
+ haoyi-mbp:Workspace haoyi$ git clone https://github.com/lihaoyi/workbench-example-app
+ Cloning into 'workbench-example-app'...
+ remote: Counting objects: 876, done.
+ remote: Total 876 (delta 0), reused 0 (delta 0)
+ Receiving objects: 100% (876/876), 676.59 KiB | 317.00 KiB/s, done.
+ Resolving deltas: 100% (308/308), done.
+ Checking connectivity... done.
+ haoyi-mbp:Workspace haoyi$ cd workbench-example-app/
+ haoyi-mbp:workbench-example-app haoyi$ sbt ~fastOptJS
+ [info] Loading global plugins from /Users/haoyi/.sbt/0.13/plugins
+ [info] Updating {file:/Users/haoyi/.sbt/0.13/plugins/}global-plugins...
+ [info] Resolving org.fusesource.jansi#jansi;1.4 ...
+ [info] Done updating.
+ [info] Loading project definition from /Users/haoyi/Dropbox (Personal)/Workspace/workbench-example-app/project
+ [info] Updating {file:/Users/haoyi/Dropbox%20(Personal)/Workspace/workbench-example-app/project/}workbench-example-app-build...
+ [info] Resolving org.fusesource.jansi#jansi;1.4 ...
+ [info] Done updating.
+ [info] Set current project to Example (in build file:/Users/haoyi/Dropbox%20(Personal)/Workspace/workbench-example-app/)
+ [INFO] [10/26/2014 15:42:09.791] [SystemLol-akka.actor.default-dispatcher-2] [akka://SystemLol/user/IO-HTTP/listener-0] Bound to localhost/127.0.0.1:12345
+ [info] Updating {file:/Users/haoyi/Dropbox%20(Personal)/Workspace/workbench-example-app/}workbench-example-app...
+ [info] Resolving jline#jline;2.12 ...
+ [info] Done updating.
+ [info] Compiling 1 Scala source to /Users/haoyi/Dropbox (Personal)/Workspace/workbench-example-app/target/scala-2.11/classes...
+ [info] Fast optimizing /Users/haoyi/Dropbox (Personal)/Workspace/workbench-example-app/target/scala-2.11/example-fastopt.js
+ [info] workbench: Checking example-fastopt.js
+ [info] workbench: Refreshing http://localhost:12345/target/scala-2.11/example-fastopt.js
+ [success] Total time: 11 s, completed Oct 26, 2014 3:42:21 PM
+ 1. Waiting for source changes... (press enter to interrupt)
+
+@p
+ The line @code{Waiting for source changes...} is telling you that your Scala.js program is ready! Now, when you go to the web URL @code{http://localhost:12345/target/scala-2.11/classes/index-dev.html} in your browser, you should see the following:
+
+ @img(src:="images/Hello World.png", maxWidth:="100%")
+
+@p
+ Congratulations, you just built and ran your first Scala.js application! If something here does not happen as expected, it means that one of the steps did not complete successfully. Make sure you can get this working before you proceed onward.
+
+@sect{Opening up the Project}
+
+ @p
+ The next thing to do once you have the project built and running in your browser is to load it into your editor. Both IntelliJ and Eclipse should let you import the Scala.js project without any hassle. Opening it and navigating to @code{ScalaJSExample.scala} would look like this:
+
+ @img(src:="images/IntelliJ Hello.png", maxWidth:="100%")
+
+ @p
+ Let's try changing one line to change the background fill from black to white:
+
+ @hl.diff
+ - ctx.fillStyle = "black"
+ + ctx.fillStyle = "white"
+
+ @p
+ Because we started ran @code{sbt ~fastOptJS} with the @code{~} prefix earlier, it should pick up the change and automatically recompile. The example project is set up to automatically refresh the page when recompilation is complete.
+
+ @img(src:="images/Hello World White.png", maxWidth:="100%")
+
+ @p
+ If you open up your browser's developer console, you'll see that the SBT log output is being mirrored there:
+
+ @img(src:="images/Hello World Console.png", maxWidth:="100%")
+
+ @p
+ Apart from the SBT log output (which is handled by Workbench) any @hl.scala{println}s in your Scala.js code will also end up in the browser console (the @code{main} you see in the console is printed inside the Scala.js application, see if you can find it!) and so will the stack traces for any thrown exceptions.
+
+@sect{The Application Code}
+
+ @p
+ We've downloaded, compiled, ran, and made changes to our first Scala.js application. Let's now take a closer look at the code that we just ran:
+
+ @hl.ref("output/temp/src/main/scala/example/ScalaJSExample.scala")
+
+ @p
+ It's a good chunk of code, though not a huge amount. To someone who didn't know about Scala.js, they would just think it's normal Scala, albeit with this unusual @hl.scala{dom} library and a few weird annotations. Let's pick it apart starting from the top:
+
+ @hl.ref("output/temp/src/main/scala/example/ScalaJSExample.scala", "case class Point", "@JSExport")
+
+ @p
+ Here we are defining a @hl.scala{Point} case class which represents a X/Y position, with some basic operators defined on it. This is done mostly for convenience later on, when we want to manipulate these two-dimensional points. Scala.js is Scala, and supports the entirety of the Scala language. @hl.scala{Point} here behaves identically as it would if you had run Scala on the JVM.
+
+ @hl.ref("output/temp/src/main/scala/example/ScalaJSExample.scala", "@JSExport", "val ctx")
+
+ @p
+ This @hl.scala("@JSExport") annotation is used to tell Scala.js that you want this method to be visible and callable from Javascript. By default, Scala.js does dead code elimination and removes any methods or classes which are not used. This is done to keep the compiled executables a reasonable size, since most projects use only a small fraction of e.g. the standard library. @hl.scala("@JSExport") is used to tell Scala.js that the @hl.scala{ScalaJSExample} object and its @hl.scala{def main} method are entry points to the program. Even if they aren't called anywhere internally, they are called externally by Javascript that the Scala.js compiler is not aware of, and should not be removed.
+
+ @p
+ Apart from this annotation, @hl.scala{ScalaJSExample} is just a normal Scala @hl.scala{object}, and behaves like one in every way. Note that the main-method in this case takes a @hl.scala{dom.HTMLCanvasElement}: your exported methods can have any signature, with arbitrary arity or types for parameters or the return value. This is in contrast to the main method on the JVM which always takes an @hl.scala{Array[String]} and returns @hl.scala{Unit}. In fact, there's nothing special about this method at all! It's like any other exported method, we just happen to attribute it the "main" entry point.
+
+ @hl.ref("output/temp/src/main/scala/example/ScalaJSExample.scala", "val ctx", "var count")
+
+ @p
+ Here we are retrieving a handle to the canvas we will draw on using @hl.scala{document.getElementById}, and from it we can get a @hl.scala{dom.CanvasRenderingContext2D} which we actually use to draw on it.
+
+ @p
+ @hl.scala{document.getElementById} is the exact same API that's used in normal Javascript, as documented @a("here", href:="https://developer.mozilla.org/en-US/docs/Web/API/document.getElementById"). In fact, the entire @hl.scala{org.scalajs.dom} namespace (imported at the top of the file) comprises statically typed facades for the javascript APIs provided by the browser.
+
+ @p
+ We need to perform the @hl.scala{asInstanceOf} call because depending on what you pass to @hl.scala{getElementById} and @hl.scala{getContext}, you could be returned elements and contexts of different types. Hence we need to tell the compiler explicitly that we're expecting a @hl.scala{dom.HTMLCanvasElement} and @hl.scala{dom.CanvasRenderingContext2D} back from these methods for the strings we passed in.
+
+ @hl.ref("output/temp/src/main/scala/example/ScalaJSExample.scala", "def run", "dom.setInterval")
+
+ @p
+ This is the part of the Scala.js program which does the real work. It runs 10 iterations of a @a("small algorithm", href:="http://en.wikipedia.org/wiki/Sierpinski_triangle#Chaos_game") that generates a Sierpinski Triangle point-by-point. The steps, as described by the linked article, are roughly:
+
+ @ul
+ @li
+ Pick a random corner of the large-triangle
+ @li
+ Move your current-position @hl.scala{p} halfway between its current location and that corner
+ @li
+ Draw a dot
+ @li
+ Repeat
+
+ @p
+ In this example, the triangle is hard-coded to be 255 pixels high by 255 pixels wide, and some math is done to pick a color for each dot which will give the triangle a pretty gradient.
+
+ @hl.ref("output/temp/src/main/scala/example/ScalaJSExample.scala", "dom.setInterval")
+
+ @p
+ Now this is the call that actually does the useful work. All this method does is call @hl.scala{dom.setInterval}, which tells the browser to run the @hl.scala{run} method every 50 milliseconds. As mentioned earlier, the @hl.scala{dom.*} methods are simply facades to their native Javascript equivalents, and @hl.scala{dom.setInterval} is @a("no different", href:="https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers.setInterval"). Note how you can pass a Scala lambda to @hl.scala{setInterval} to have it called by the browser, where in Javascript you'd need to pass a Javascript @hl.javascript{function(){...}}
+
+@sect{The Project Code}
+
+ @p
+ We've already taken a look at the application code for a simple, self-contained Scala.js application, but this application is not @i{entirely} self contained. It's wrapped in a small SBT project that sets up the necessary dependencies and infrastructure for this application to work.
+
+ @sect{project/build.sbt}
+ @hl.ref("output/temp/project/build.sbt")
+
+ @p
+ This is the list of SBT plugins used by this small example application. There are two of them: the Scala.js plugin (which contains the Scala.js compiler and other things, e.g. tasks such as @code{fastOptJS}) and the @a("Workbench", href:="https://github.com/lihaoyi/workbench") plugin, which is used to provide the auto-reload-on-change behavior and the forwarding of SBT logspam to the browser console.
+
+ @p
+ Of the two, only the Scala.js plugin is really necessary. The Workbench plugin is a convenience that makes development easier. Without it you'd need to keep a terminal open to view the SBT logspam, and manually refresh the page when compilation finished. Not the end of the world.
+
+
+ @sect{build.sbt}
+ @hl.ref("output/temp/build.sbt")
+
+ @p
+ The @code{build.sbt} project file for this application is similarly unremarkable: It includes the settings for the two SBT plugins we saw earlier, as well as boilerplate @hl.scala{name}/@hl.scala{version}/@hl.scala{scalaVersion} values common to all projects.
+
+ @p
+ Of interest is the @hl.scala{libraryDependencies}. In Scala-JVM, this key is used to declare dependencies on libraries from Maven Central, so you can use them in your Scala-JVM projects. In Scala.js, the same key is used to declare dependencies on libraries so you can use them in your Scala.js projects! Re-usable libraries can be built and published with Scala.js just as you do on Scala-JVM, and here we make use of one which provides the typed facades with which we used to access the DOM in the application code.
+
+ @p
+ Lastly, we have two Workbench related settings: @hl.scala{bootSnippet} basically tells Workbench how to restart your application when a new compilation run finishes, and @hl.scala{updateBrowsers} actually tells it to perform this application-restarting.
+
+ @sect{src/main/resources/index-dev.html}
+ @hl.ref("output/temp/src/main/resources/index-dev.html")
+
+ @p
+ This is the HTML page which our toy app lives in, and the same page that we have so far been using to view the app in the browser. To anyone who has used HTML, most of it is probably familiar. Things of note are the Script tags: @hl.scala{"../example-fastopt.js"} Is the executable blob spat out by the compiler, which we need to include in the HTML page for anything to happen. This is where the results of your compiled Scala code appear. @hl.scala{"workbench.js"} is the client for the Workbench plugin that connects to SBT, reloads the browser and forwards logspam to the browser console.
+
+ @p
+ The @hl.scala{ScalaJSExample().main()} call is what kicks off the Scala.js application and starts its execution. Scala.js follows Scala semantics in that @hl.scala{object}s are evaluated lazily, with no top-level code allowed. This is in contrast to Javascript, where you can include top-level statements and object-literals in your code which execute immediately. In Scala.js, nothing happens when @code{../example-fastopt.js} is imported! We have to call the main-method first. In this case, we're passing the canvas object (attained using @hl.javascript{getElementById}) to it so it knows where to do its thing.
+
+ @p
+ Lastly, only @hl.scala("@JSExport")ed objects and methods can be called from Javascript. Also, although this example only exports the @hl.scala{main} method which is called once, there is nothing stopping you from exporting any number of objects and methods and calling them whenever you need to. In this way, you can easily make a Scala.js "library" which is available to external Javascript as an API.
+
+@sect{Publishing}
+ @p
+ The last thing that we'll do with our toy application is to publish it. If you look in the @code{target/scala2.11} folder, you'll see the output of everything we've done so far:
+
+ @hl.bash
+ target/scala-2.11
+ ├── classes
+ │   ├── JS_DEPENDENCIES
+ │   ├── example
+ │   │   ├── Point$.class
+ │   │   ├── Point$.sjsir
+ │   │   ├── Point.class
+ │   │   ├── Point.sjsir
+ │   │   ├── ScalaJSExample$$anonfun$main$1.class
+ │   │   ├── ScalaJSExample$$anonfun$run$1.class
+ │   │   ├── ScalaJSExample$.class
+ │   │   ├── ScalaJSExample$.sjsir
+ │   │   └── ScalaJSExample.class
+ │   ├── index-dev.html
+ │   └── index-opt.html
+ ├── example-fastopt.js
+ └── example-fastopt.js.map
+
+ @p
+ All the @code{.class} and @code{.sjsir} files are the direct output of the Scala.js compiler, and aren't necessary to actually run the application. The only two files necessary are @code{index-dev.html} and @code{example-fastopt.js}. You may recognize @code{index-dev.html} as the file that we were navigating to in the browser earlier.
+
+ @p
+ These two files can be extracted and published as-is: you can put them on @a("Github-Pages", href:="https://pages.github.com/"), @a("Amazon Web Services", href:="http://docs.aws.amazon.com/gettingstarted/latest/swh/website-hosting-intro.html"), or a hundred other places. However, one thing of note is the fact that the generated Javascript file is quite large:
+
+ @hl.bash
+ haoyi-mbp:temp haoyi$ du -h target/scala-2.11/example-fastopt.js
+ 856K target/scala-2.11/example-fastopt.js
+
+ @p
+ 856 Kilobytes for a hello world app! That is clearly too large. If you examine the contents of the file, you'll see that your code has been translated into something like this:
+
+ @hl.javascript
+ var i$2 = i;
+ if (((ScalaJS.m.Lexample_ScalaJSExample().count$1 % 30000) === 0)) {
+ ScalaJS.m.Lexample_ScalaJSExample().clear__V()
+ };
+ ScalaJS.m.Lexample_ScalaJSExample().count$1 = ((ScalaJS.m.Lexample_ScalaJSExample().count$1 + 1) | 0);
+ var jsx$3 = ScalaJS.m.Lexample_ScalaJSExample();
+ var jsx$2 = ScalaJS.m.Lexample_ScalaJSExample().p$1;
+ var jsx$1 = ScalaJS.m.Lexample_ScalaJSExample().corners$1;
+ var this$5 = ScalaJS.m.s_util_Random();
+ jsx$3.p$1 = jsx$2.$$plus__Lexample_Point__Lexample_Point(ScalaJS.as.Lexample_Point(jsx$1.apply__I__O(this$5.self$1.nextInt__I__I(3)))).$$div__I__Lexample_Point(2);
+ var height = (512.0 / ((255 + ScalaJS.m.Lexample_ScalaJSExample().p$1.y$1) | 0));
+ var r = ((ScalaJS.m.Lexample_ScalaJSExample().p$1.x$1 * height) | 0);
+ var g = ((((255 - ScalaJS.m.Lexample_ScalaJSExample().p$1.x$1) | 0) * height) | 0);
+
+ @p
+ As you can see, this code is still very verbose, with lots of unnecessarily long identifiers such as @hl.javascript{Lexample_ScalaJSExample} in it. This is because we've only performed the @i{fast optimization} on this file, to try and keep the time taken to edit -> compile while developing reasonably short.
+
+ @sect{Full Optimization}
+ @p
+ If we're planning on publishing the app for real, we can run the @i{full optimization}. This takes several seconds longer than the @i{fast optimization}, but results in a significantly smaller and leaner output file @code{example-opt.js}.
+
+ @hl.bash
+ haoyi-mbp:temp haoyi$ du -h target/scala-2.11/example-opt.js
+ 144K target/scala-2.11/example-opt.js
+
+ @p
+ 144 Kilobytes! Better. Not great, though! In general, Scala.js does not produce tiny executables, although the output size of the compiled executables is dropping all the time. If you look inside that file, you'll see all of the long identifiers have been replaced by short ones by the Google Closure Compiler.
+
+ @hl.javascript("""
+ Rb(P(),N(r(L(Ea),["rgb(",", ",", ",")"])))),Sb(P(),r(L(K),[n,s,C])));fe().te.fillRect(fe().Oc.jc,fe().Oc.kc,1,1);e=e+1|0;c=c+k|0}},50))}ae.prototype.Zf=function(){this.te.fillStyle="black";this.te.fillRect(0,0,255,255)};ae.prototype.main=function(){return ee(),void 0};ae.prototype.a=new I({lj:0},!1,"example.ScalaJSExample$",K,{lj:1,b:1});var be=void 0;function fe(){be||(be=(new ae).c());return be}ba.ScalaJSExample=fe;function le(){}le.prototype=new J;function me(){}me.prototype=le.prototype;
+ """)
+
+ @p
+ These files are basically unreadable, but nonetheless behave the same as the @code{-fastopt} versions. Try it out by opening the @code{index-opt.html} file in the @code{target/scala-2.11/classes} directory with your browser: you should see the thing as when opening @code{index-dev}, except it will be pulling in the fully-optmized version of your application.
+
+ @p
+ This means you can develop and debug using @code{fastOptJS}, and only spend the extra time (and increased debugging-difficulty) on the @code{fullOptJS} version just as you're going to publish it, with the assurance that although the code is much more compact, its behavior will not change.
+
+ @sect{Blob Size}
+ @p
+ Even the fully-optimized version of our toy Scala.js app are pretty large. There are some factors that mitigate the large size of these executables:
+
+ @ul
+ @li
+ A large portion of this 144k is the Scala standard library, and so the size of the compiled blob does not grow that fast as your program grows. For example, while this ~50 line application is 144k, a much larger ~2000 line application is only 288k.
+ @li
+ This size is pre-@a("gzip", href:="http://en.wikipedia.org/wiki/Gzip"), and most webservers serve their contents compressed via gzip to reduce the download size. Gzip cuts the actual download size down to 43k, which is more acceptable.
+
+ @p
+ And there is ongoing work to shrink the size of these executables. If you want to read more about this, check out the section on the Scala.js File Encoding and the Optimization Pipeline.
+
+ @hr
+
+ @p
+ In general, all the output of the Scala.js compiler is bundled up into the @code{example-fastopt.js} and @code{example-opt.js} files. As a first approximation, these files can be included directly on a HTML page (as we have here, with @code{index-dev.html} and @code{index-opt.html}) and published together as a working web app. Even zipping them up and emailing them to a friend is sufficient to give someone a working, live version of your hard work!
+
+ @p
+ More advanced users would want to integrate them into their build process or serve them from a web server, all of which is entirely possible. You just need to run the Scala.js compiler and place the output @code{.js} file somewhere your web server can pick it up, e.g. in some static-resource folder. We cover an example setup of this with a Scala webserver in our Client Server Integration chapter.
+
+@sect{Recap}
+
+ @p
+ If you've made it this far, you've downloaded, made modifications to, and published a toy Scala.js application. At the same time, we've gone over many of the key concepts in the Scala.js development process:
+
+ @ul
+ @li
+ Getting a Scala.js application
+ @li
+ Building it and seeing it work in the browser
+ @li
+ Made modifications to it to see it update
+ @li
+ Examined the source code to try and understand what it's doing
+ @li
+ Examined the output code, at two levels of optimization, to see how the Scala.js compiler works
+ @li
+ Packaged the application in a form that can be easily published online
+
+ @p
+ Hopefully this gives a good sense of the workflow involved in developing a Scala.js application end-to-end, as well as a feel for the magic involved in the compilation process. Nevertheless, we have barely written any Scala.js code itself!
+
+ @p
+ Since you have a working development environment set up, you should take this time to poke around what you can do with our small Sierpinski-Triangle drawing app. Possible exercises include:
+
+ @ul
+ @li
+ Javascript includes APIs for @a("getting the size of the window", href:="http://stackoverflow.com/questions/1248081/get-the-browser-viewport-dimensions-with-javascript") and @a("changing the size of a canvas", href:="http://stackoverflow.com/questions/9251480/set-canvas-size-using-javascript"). These Javascript APIs are available in Scala.js, and we've already used some of them in the course of this example. Try making the Canvas full-screen, and re-positioning the corners of the triangle to match.
+ @li
+ The @hl.scala{dom.CanvasRenderingContext2D} has a bunch of methods on it that can be used to draw things. Here we only draw 1x1 rectangles to put points on the canvas; try modifying the code to make it draw something else.
+ @li
+ We've look at the @code{master} branch of @code{workbench-example-app}, but this project also has several other branches showing off different facets of Scala.js: @a("dodge-the-dots", href:="https://github.com/lihaoyi/workbench-example-app/tree/dodge-the-dots") and @a("space-invaders", href:="https://github.com/lihaoyi/workbench-example-app/tree/space-invaders") are both interesting branches worth playing with as a beginner. Check them out!
+ @li
+ Try publishing the output code somewhere. You only need @code{example-opt.js} and @code{index-opt.html}; try putting them somewhere online where the world can see it.
+
+ @p
+ When you're done poking around our toy web application, read on to the next chapter, where we will explore making something more meaty using the Scala.js toolchain!
diff --git a/book/src/main/scalatex/book/Index.scalatex b/book/src/main/scalatex/book/Index.scalatex
new file mode 100644
index 0000000..af17e0e
--- /dev/null
+++ b/book/src/main/scalatex/book/Index.scalatex
@@ -0,0 +1,30 @@
+
+@sect("Hands-on Scala.js")
+ @div(cls:="pure-g")
+ @div(cls:="pure-u-1 pure-u-md-13-24")
+ @hl.ref("examples/src/main/scala/Splash.scala", "var x")
+
+ @div(cls:="pure-u-1 pure-u-md-11-24")
+ @canvas(id:="canvas1", display:="block")
+ @script("Splash().main(document.getElementById('canvas1'))")
+
+ @p
+ @a("Scala.js", href:="http://www.scala-js.org/") is a compiler that compiles Scala source code to equivalent Javascript code. That lets you write Scala code that you can run in a web browser, or other environments (Chrome plugins, Node.js, etc.) where Javascript is supported.
+
+ @p
+ This book contains something for all levels of experience with Scala.js: absolute beginners can get started with the Introduction and Hands-on tutorial, people who have used it before can skip ahead to the later parts of the tutorial, building a canvas app or dynamic HTML page. Intermediate users will find the chapters on cross-publishing a Scala.js library interesting, and even experienced users will find the In-depth Documention useful.
+
+ @sect("Intro to Scala.js")
+ @Intro.template
+
+ @sect("Getting Started")
+ @GettingStarted.template
+
+ @sect("Making a Canvas App")
+ @CanvasApp.template
+
+ @sect("Interactive Web Pages")
+ @WebPage.template
+
+
+
diff --git a/book/src/main/scalatex/book/Intro.scalatex b/book/src/main/scalatex/book/Intro.scalatex
new file mode 100644
index 0000000..f2cc17f
--- /dev/null
+++ b/book/src/main/scalatex/book/Intro.scalatex
@@ -0,0 +1,189 @@
+@p
+ Scala.js compiles Scala code to equivalent, executable Javascript. Here's the compilation of a trivial hello-world example:
+
+@div(cls:="pure-g")
+ @div(cls:="pure-u-1 pure-u-md-1-2")
+ @hl.scala
+ object Example extends js.JSApp{
+ def main() = {
+ var x = 0
+ while(x < 10) x += 3
+ println(x)
+ }
+ }
+
+ @div(cls:="pure-u-1 pure-u-md-1-2")
+ @hl.javascript
+ ScalaJS.c.LExample$.prototype.main__V = (function() {
+ var x = 0;
+ while ((x < 10)) {
+ x = ((x + 3) | 0)
+ };
+ ScalaJS.m.s_Predef().println__O__V(x)
+ });
+
+@p
+ As you can see, both of the above programs do identical things: it's just that the one on the left is written in Scala and the one on the right is in Javascript.
+
+@p
+ Traditionally, Scala has been a language which runs on the JVM. This eliminates it from consideration in many cases, e.g. when you need to build interactive web apps, you need to fall back to Javascript to run your client-side code, at a great loss in terms of toolability and maintainability. Scala.js lets you to develop web applications with the safety and toolability that comes with a statically typed language:
+
+@ul
+ @li
+ Typo-safety due to its compiler which catches many silly errors before the code is run
+ @li
+ In-editor support for autocomplete, error-highlghting, refactors, and intelligent navigation
+ @li
+ Very small compiled executables, in the 100-400kb range
+ @li
+ Source-maps for ease of debugging
+
+@p
+ The value proposition is that due to the superior language and tooling, writing a web application in Scala.js will result in a codebase that is more flexible and robust than an equivalent application written in Javascript.
+
+@sect{About Javascript}
+ @p
+ Javascript is the language supported by web browsers, and is the only language available if you wish to write interactive web applications. As more and more activity moves online, the importance of web apps will only increase over time.
+
+ @sect{Javascript-the-language}
+ @p
+ However, Javascript is not an easy language to work in. Apart from being untyped (which some people don't mind) Javascript is also extremely verbose, has a lot of surprising behavior, and has a culture that make even the simplest of patterns (e.g. instantiating an object) a debate between a dozen different and equally-bad options.
+ @p
+ To work in Javascript, you need the discipline to limit yourself to the sane subset of the language, avoiding all the pitfalls along the way:
+
+ @img(src:="images/javascript-the-good-parts-the-definitive-guide.jpg")
+
+ @sect{Javascript-the-platform}
+ @p
+ However, even as Javascript-the-language sucks, Javascript-the-platform has some very nice properties that make it a good target for application developers:
+
+ @ul
+ @li
+ Zero-install distribution: just go to a URL and have the application downloaded and ready to use.
+ @li
+ Hyperlinks: being able to link to a particular page or item within a web app is a feature other platforms lack, and makes it much easier to cross-reference between different systems
+ @li
+ Sandboxed security: before the advent of mobile apps, web apps were the most secure runtime available, offering none of the risk or worry that comes with installing desktop software
+
+ @p
+ These features are all very nice to have, and together have made the web platform the success it is today.
+
+ @hr
+
+ @p
+ This is where Scala.js comes in. As developers we want Javascript-the-platform, with its ease-of-distribution, hyperlinks and security characteristics. We do not want Javascript-the-language, with its propensity for bugs, verbosity, and fragility.
+
+@sect{The Promise}
+
+ @p
+ Scala.js promises to save us from this mess: with Scala.js, you can cross compile your Scala code to a Javascript executable that can run on all major web browsers, thus saving you from the endless stream of gotcha's like the one below:
+
+ @hl.javascript
+ javascript> ["10", "10", "10", "10"].map(parseInt)
+ [10, NaN, 2, 3] // WTF
+
+ @hl.scala
+ scala> List("10", "10", "10", "10").map(parseInt)
+ List(10, 10, 10, 10) // Yay!
+
+ @sect{The Language}
+ @p
+ At a first approximation, Scala.js provides you a sane language to do development in the web browser. Not only do you have an expressive language with static types, you also have great tooling with IDEs like IntelliJ and Eclipse, a rich library of standard collections, and many other modern conveniences that we take for granted but are curiously missing when working in the wild west of web development: the browser!
+
+ @p
+ While not useful for small applications, where most of the logic is gluing together external APIs, this comes in very useful in large applications where a lot of the complexity and room-for-error is entirely internal. With larger apps, you can no longer blame browser vendors for confusing APIs that make your code terrible: these confusing APIs only lurk in the peripherals around a larger, complex application. One thing you learn working in large-ish web client-side code-bases is that the bulk of the confusion and complexity is no-one's fault but your own, as a team.
+
+ @p
+ At this point, all of Google, Facebook, and Microsoft have all announced work on a typed variant of Javascript. These are not academic exercises: Dart/AtScript/Flow/Typescript are all problems that solve a real need, that these large companies have all faced once they've grown beyond a certain size. Clearly, Javascript isn't cutting it anymore, and the convenience and "native-ness" of the language is more than made up for in the constant barrage of self-inflicted problems. Scala.js takes this idea and runs with it!
+
+ @sect{Shared Code}
+ @p
+ Scala.js does not just stop at writing code on the client, though! Scala itself is a very successful, capable language for writing all sorts of systems, from web servers to backend infrastructure. With Scala.js, you can utilize the same libraries you use writing your Scala servers when writing your Scala web clients! On one end, you are sharing your templating language with @a("Scalatags", href:="https://github.com/lihaoyi/scalatags") or sharing your serialization logic with @a("uPickle", href:="https://github.com/lihaoyi/upickle"). At the other, you are sharing large, abstract libraries like @a("Scalaz", href:="https://github.com/japgolly/scalaz") or @a("Shapeless", href:="https://groups.google.com/forum/#!searchin/scala-js/shapeless/scala-js/5Sf2up0z3PU/9F9SYB0qHEcJ").
+
+ @p
+ Sharing code means several things:
+
+ @ul
+ @li
+ Not having to find two libraries to do a particular common task
+ @li
+ Not having to re-learn two different ways of doing the exact same thing
+ @li
+ Not needing to implement the same algorithms twice, for the times you can't find a good library to do what you want
+ @li
+ Not having to debug problems caused by subtle differences in the two implementations
+ @li
+ Not having to resort to awkward Ajax-calls or pre-computation to avoid duplicating logic between the client and server
+
+ @p
+ Shared code doesn't just mean sharing pre-made libraries between the client and server. You can easily publish your own libraries that can be used on both Scala-JVM and Scala.js. This means that as a library author, you can at once target two completely different platforms, and (with some work) take advantage of the intricacies of each platform to optimize your library for each one. Take Scalatags as an example: as the first client-server Scala.js-ScalaJVM shared libraries, it enjoys a roughly event split of downloads from people using it on both platforms:
+
+ @img(src:="images/Scalatags Downloads.png", width:="100%")
+
+ @p
+ Shared code means that if you, as an application writer, want some logic to be available on both the client and server, you simply put it in a "shared" folder, and that's the end of the discussion. No architectural patterns to follow, no clever techniques need to be involved. Shared logic, whether that means constants, functions, data structures, all the way to algorithms and entire libraries, can simply be placed in "shared" and be instantly accessible from both your client-side web code and your server.
+
+ @p
+ Shared code has long been the holy-grail of web development. Even now, people speak of shared code as if it were a myth. With Scala.js, shared code is the simple, boring reality. And there's a lot to like in that!
+
+ @sect{Client-Server Integration}
+ @p
+ There is an endless supply of new platforms which have promised to change-the-way-we-do-web-development-forever. From old-timers like @a("Ur-Web", href:="http://www.impredicative.com/ur/"), to @a("GWT", href:="http://www.gwtproject.org/"), to Asana's @a("LunaScript", href:="https://asana.com/luna"), to more recently things like @a("Meteor.js", href:="https://www.meteor.com/").
+ @p
+ One common theme in all these platforms is that their main selling point is their tight, seamless client-server integration, to the point where you can just make method calls across the client-server boundary and the platform/language/compiler figures out what to do.
+ @p
+ With Scala.js and Scala-JVM, such conveniences like making method calls across the client-server boundary is the boring reality. Not only are the calls transparent, they are also statically checked, so any mistake in the route name or the parameters it expects, or the result type it returns to you, will be caught by the compiler long before even manual testing.
+
+ @hr
+
+ @p
+ In many ways, Scala.js all-at-once provides many of the traditional holy-grails of web development: People have always dreamed about doing web development in a sane, best-of-breed language that compiles to both client and server. Of not having to worry too hard about whether code goes on the client or on the server, and being able to move or share it if necessary. Of having a compiler that will verify and check that your entire system is correct.
+
+ @p
+ Scala.js provides all these things, and much more.
+
+@sect{The Agenda}
+
+ @p
+ This book will be roughly divided into three sections. These sections can be read in any order. Although the later chapters will make references to earlier chapters, there'll be hyperlinks so you can quickly go back and catch up on what you missed skipping over ,
+
+ @sect{Hands On}
+ @p
+ A whirlwind tour of the various things that Scala.js can be used for. We will cover:
+
+ @ul
+ @li
+ Your first Scala.js application: setting up your development environment, cloning the example repository, debugging and finally publishing your first toy application
+ @li
+ An interactive web app using Scala.js: how you interact with the HTML DOM, how you utilize Ajax calls and other browser APIs that are common in Javascript-heavy applications
+ @li
+ A Scala.js library: how to write a module that can be depended on by applications both your own and by others, and be used both with Scala.js and Scala-on-the-JVM
+ @li
+ Client-Server integration: We will build a simple web application with a Scala server and Scala.js client. In the process, we'll explore how to share code between client and server, how to get compiler-checked/boilerplate-free Ajax calls between client and server, and many other long-standing holy-grails of web development
+
+ @p
+ After going through this chapter and following along with the exercises, you should have a good sense of how Scala.js works and how it feels building things in Scala.js. You would not be an expert, but you'll know where to get started if you decide to try out Scala.js for your next project.
+
+ @sect{Scala.js in Depth}
+ @p
+ This section of the book will cover lots of content that does not fit in the earlier Hands-On portion of the book. Things that aren't immediately necessary to get something up and running, things that only advanced users would care about, things that you probably don't need to know but you'd like to know out of intellectual curiosity.
+
+ @p
+ In general, this section of the book will go much deeper into Scala.js, much more than is necessary to get your first applications built. We will talk about the small number of semantic differences between Scala.js and Scala, details of the foreign-function-interface with Javascript, the various optimization levels and what they do. Nothing pressing or urgently needed, but all very interesting, and worth reading if you want to really understand Scala.js in depth.
+
+ @sect{Why}
+ @p
+ Why should you care about Scala.js in the first place? Why not just write Javascript? As a new, barely-a-year-old project, what does it provide that other more mature compile-to-javascript langauges don't?
+
+ @p
+ In this section of the book, we will examine the reasons which got me first interested in Scala.js. We'll talk at length about the deficiencies of Javascript, the ubiquity of the browser as an application platform, and the technical characteristics that make this the case.
+
+ @p
+ Lastly, we will explore the solution space. Scala.js isn't the only game in town, and there are hundreds of over attempts at covering the same ground the Scala.js now attempts to cover. We'll compare and contrast the different approaches to see what Scala.js can bring to the table that other approaches cannot.
+
+ @hr
+
+ @p
+ As mentioned earlier, these chapters can be read in any order. In keeping with the spirit of the book, we'll jump right into the Hands On to give you the experience, and save the talking and philosophizing for later. Let's go!
+
+
diff --git a/book/src/main/scalatex/book/WebPage.scalatex b/book/src/main/scalatex/book/WebPage.scalatex
new file mode 100644
index 0000000..aa45699
--- /dev/null
+++ b/book/src/main/scalatex/book/WebPage.scalatex
@@ -0,0 +1,132 @@
+@p
+ Most web applications aren't neat little games which live on a single canvas: they are large, structured HTML pages, which involve displaying data (whether from the user or from the web) in multiple ways, while allowing the user to make changes to the data that can be saved back to whatever remote web-service/database it came from.
+
+@p
+ At this point, you are already competent at using Scala.js to make basic, self-contained canvas applications. In this chapter, we will cover how to use Scala.js to build the sort of interactive-web-pages that make up the bulk of the modern-day internet. We'll cover how to use powerful libraries that turn front-end development form the typical fragile-mess into a structured, robust piece of software.
+
+@sect{Hello World: HTML}
+
+ @p
+ The most basic way of building interactive web pages using Scala.js is to use the Javascript APIs to blat HTML strings directly into some container div, often @code{document.body}. This approach works, as the following code snippet demonstrates:
+
+ @div(cls:="pure-g")
+ @div(cls:="pure-u-1 pure-u-md-13-24")
+ @hl.ref("examples/src/main/scala/webpage/HelloWorld0.scala")
+
+ @div(cls:="pure-u-1 pure-u-md-11-24")
+ @div(id:="div1")
+ @script("HelloWorld0().main(document.getElementById('div1'))")
+
+ @p
+ This approach works, as the above example shows, but has a couple of disadvantages:
+
+ @ul
+ @li
+ It is untyped: it is easy to accidentally mistype something, and result in malformed HTML. A typo such as @hl.html{<dvi>} would go un-noticed at build-time. Depending on where the typo happens, it could go un-noticed until the application is deployed, causing subtle bugs that only get resolved much later.
+ @li
+ It is insecure: @a("Cross-site Scripting", href:="http://en.wikipedia.org/wiki/Cross-site_scripting") is a real thing, and it is easy to forget to escape the values you are putting into your HTML strings. Above they're constants like @hl.scala{"dog"}, but if they're user-defined, you may not notice there is a problem until something like @hl.scala{"<script>...</script>"} sneaks through and your users' accounts & data is compromised.
+
+ @p
+ There are more, but we won't go deep into the intricacies of these problems. Suffice to say it makes mistakes easy to make and hard to catch, and we have something better...
+
+@sect{Scalatags}
+ @p
+ @a("Scalatags", href:="https://github.com/lihaoyi/scalatags") is a cross-platform Scala.js/Scala-JVM library that is designed to generate HTML. To use Scalatags, you need to add it as a dependency to your Scala.js SBT project, in the @code{build.sbt} file:
+
+ @hl.ref("examples/build.sbt", "com.scalatags")
+
+ @p
+ With that, the above snippet of code re-written using Scalatags looks as follows:
+
+ @div(cls:="pure-g")
+ @div(cls:="pure-u-1 pure-u-md-13-24")
+ @hl.ref("examples/src/main/scala/webpage/HelloWorld1.scala")
+
+ @div(cls:="pure-u-1 pure-u-md-11-24")
+ @div(id:="div2")
+ @script("HelloWorld1().main(document.getElementById('div2'))")
+
+ @p
+ Scalatags has some nice advantages over plain HTML: it's type-safe, so typos like @hl.scala{dvi} get caught at compile-time. It's also secure, such that you don't need to worry about script-tags in strings or similar. The @a("Scalatags Readme", href:="https://github.com/lihaoyi/scalatags#scalatags") elaborates on these points and other advantages. As you can see, it takes just 1 import at the top of the file to bring it in scope, and then you can use all of Scalatags' functionality.
+
+ @p
+ The Scalatags github page has @a("comprehensive documentation", href:="https://github.com/lihaoyi/scalatags#hello-world") on how to express all manner of HTML fragments using Scalatags, so anyone who's familiar with how HTML works can quickly get up to speed. Instead of a detailed listing, we'll walk through some interactive examples to show Scalatags in action!
+
+ @sect{User Input}
+ @div(cls:="pure-g")
+ @div(cls:="pure-u-1 pure-u-md-13-24")
+ @hl.ref("examples/src/main/scala/webpage/Inputs.scala", "val box")
+
+ @div(cls:="pure-u-1 pure-u-md-11-24")
+ @div(id:="div3")
+ @script("Inputs().main(document.getElementById('div3'))")
+
+ @p
+ In Scalatags, you build up fragments of type @hl.scala{Frag} using functions like @hl.scala{div}, @hl.scala{h1}, etc., and call @hl.scala{.render} on it to turn it into a real @hl.scala{dom.Element}. Different fragments render to different things: e.g. @hl.scala{input.render} gives you a @hl.scala{dom.HTMLInputElement}, @hl.scala{span.render} gives you a @hl.scala{dom.HTMLSpanElement}. You can then access the properties of these elements: adding callbacks, checking their value, anything you want.
+
+ @p
+ In this example, we render and @hl.scala{input} element and a @hl.scala{span}, wire up the input to set the value of the span whenever you press a key in the input, and then stuff both of them into a larger HTML fragment that forms the contents of our @hl.scala{target} element.
+
+ @sect{Re-rendering}
+ @p
+ Let's look at a slightly longer example. While above we spliced small snippets of text into the DOM, here we are going to re-render entire sections of HTML! The goal of this little exercise is to make a filtering search-box: starting from a default list of items, narrow it down as the user enters text into the box.
+
+ @p
+ To begin with, let's define our list of items: Fruits!
+
+ @hl.ref("examples/src/main/scala/webpage/Search0.scala", "val listings", "def")
+
+ @p
+ Next, let's think about how we want to render these fruits. One natural way would be as a list, which in HTML is represented by a @hl.html{<ul>} with @hl.html{<li>}s inside of it if we wanted the list to be unordered. We'll make it a @hl.scala{def}, because we know up-front we're going to need to re-render this listing as the search query changes. Lastly, we know we want 1 list item for each fruit, but only if the fruit starts with the search query.
+
+ @hl.ref("examples/src/main/scala/webpage/Search0.scala", "def renderListings", "lazy val")
+
+ @p
+ Using a @hl.scala{for}-loop with a filter inside the Scalatags fragment is just normal Scala, since you can nest arbitrary Scala expressions inside a Scalatags snippet. In this case, we're converting both the fruit and the search query to lower case so we can compare them case-insensitively.
+
+ @p
+ Lastly, we just need to define the input box and output-container (as we did earlier), set the @hl.scala{onkeyup} event handler, and place it in a larger fragment, and then into our target:
+
+ @div(cls:="pure-g")
+ @div(cls:="pure-u-1 pure-u-md-13-24")
+ @hl.ref("examples/src/main/scala/webpage/Search0.scala", "val output")
+
+ @div(cls:="pure-u-1 pure-u-md-11-24")
+ @div(id:="div4")
+ @script("Search0().main(document.getElementById('div4'))")
+
+ @p
+ And there you have it! A working search box. This is a relatively self-contained example: all the items its searching are available locally, no Ajax calls, and there's no fancy handling of the searched items. If we want to, for example, highlght the matched section of each fruit's name, we can modify the @hl.scala{def renderListings} call to do so:
+
+ @div(cls:="pure-g")
+ @div(cls:="pure-u-1 pure-u-md-13-24")
+ @hl.ref("examples/src/main/scala/webpage/Search1.scala", "def renderListings", "lazy val")
+
+ @div(cls:="pure-u-1 pure-u-md-11-24")
+ @div(id:="div5")
+ @script("Search1().main(document.getElementById('div5'))")
+
+ @p
+ Here, instead of sticking the name of the matched fruits directly into the @hl.scala{li}, we instead first split off the part which matches the query, and then highlght the first section yellow. Easy!
+
+ @hr
+
+ @p
+ Hopefully this has given you a good overview of how to do things using Scala.js and Scalatags. I won't go too deep into the various ways you can use Scalatags: the @a("documentation", href:="https://github.com/lihaoyi/scalatags") should cover most of it. Now that you've gone through this experience, it's worth re-iterating a few things you've probably already noticed about Scalatags
+
+ @ul
+ @li
+ It's safe! If you make a trivial syntactic mistake, the compiler will catch it, because Scalatags is plain Scala
+ @li
+ It's composable! You can easily define fragments and assign them to variables, to be used later. You can break apart large Scalatags fragments the same way you break apart normal code, avoiding the huge monolithic HTML templates that are common in other templating systems.
+ @li
+ It's Scala! You have the full power of the Scala language to write your fragments. No need to learn special syntax/cases for conditionals or repetitions: you can use plain-old-scala if-elses, for-loops, etc.
+
+ @p
+ Now that you've gotten a quick overview of the kinds of things you can do with Scalatags, let's move on to the next section of our hands-on tutorial...
+
+@sect{Using Web Services}
+
+ @p
+ One half of the web application faces forwards towards the user, managing and rendering HTML or Canvas for the user to view and interact with. Another half faces backwards, talking to various web-services or databases which turn the application from a standalone-widget into part of a greater whole. We've already seen how to make the front half, let's now talk about working with the back half.
+