Skip to content
76 changes: 44 additions & 32 deletions doc/calling-javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,37 @@ types.
The core type hierarchy is as follows:

js.Any
+- js.Number
+- js.Boolean
+- js.String
+- js.Undefined
+- js.Object
+- js.Date
+- js.RegExp
+- js.Array[A]
+- js.Function
+- js.Function0[+R]
+- js.Function1[-T1, +R]
+- ...
+- js.Function22[-T1, ..., -T22, +R]
+- js.ThisFunction
+- js.ThisFunction0[-T0, +R]
+- js.ThisFunction1[-T0, -T1, +R]
+- ...
+- js.ThisFunction21[-T0, ..., -T21, +R]

A value of any of these types is encoded as is in JavaScript, without boxing.
| +- js.Date
| +- js.RegExp
| +- js.Array[A]
| +- js.Dictionary[A]
| +- js.Function
| +- js.Function0[+R]
| +- js.Function1[-T1, +R]
| +- ...
| +- js.Function22[-T1, ..., -T22, +R]
| +- js.ThisFunction
| +- js.ThisFunction0[-T0, +R]
| +- js.ThisFunction1[-T0, -T1, +R]
| +- ...
| +- js.ThisFunction21[-T0, ..., -T21, +R]
+- js.prim.Number
+- js.prim.Boolean
+- js.prim.String
+- js.prim.Undefined


Note that the types in the `prim` package should not directly be used,
since they have a direct correspondance in Scala (see the
[interoperability](./js-interoperability.html) page). The reason they
exist is that for example a `scala.Double` can be stored in a variable
of type `js.Any` (through implicit conversion to `js.prim.Number`).

A value of any of these types is encoded as is in JavaScript, without wrapping.
Even when such a value is assigned to a `val` of type `scala.Any` or of a
generic type, there is no boxing. E.g., a `js.Array[js.Number]` is a JavaScript
`Array` which contains JavaScript `number`'s at runtime (not some boxing of
`number`'s).
generic type, there is no boxing. E.g., a `js.Array[js.Date]` is a JavaScript
`Array` which contains JavaScript `Date`'s at runtime.

These types have all the fields and methods available in the JavaScript API.

Expand All @@ -59,11 +66,11 @@ There are implicit conversions from corresponding Scala types and back:
<tr><th>Scala type</th><th>JavaScript type</th></tr>
</thead>
<tbody>
<tr><td>Byte<br/>Short<br/>Int<br/>Long<br/>Float<br/>Double</td><td>js.Number</td></tr>
<tr><td colspan="2">(from js.Number to Double only)</td></tr>
<tr><td>Boolean</td><td>js.Boolean</td></tr>
<tr><td>java.lang.String</td><td>js.String</td></tr>
<tr><td>Unit</td><td>js.Undefined</td></tr>
<tr><td>Byte<br/>Short<br/>Int<br/>Long<br/>Float<br/>Double</td><td>js.prim.Number</td></tr>
<tr><td colspan="2">(from js.prim.Number to Double only)</td></tr>
<tr><td>Boolean</td><td>js.prim.Boolean</td></tr>
<tr><td>java.lang.String</td><td>js.prim.String</td></tr>
<tr><td>Unit</td><td>js.prim.Undefined</td></tr>
<tr><td>Array[A]</td><td>js.Array[A]</td></tr>
<tr><td rowspan="2">FunctionN[T1, ..., TN, R]</td><td>js.FunctionN[T1, ..., TN, R]</td></tr>
<tr> <td>js.ThisFunction{N-1}[T1, ..., TN, R]</td></tr>
Expand All @@ -75,13 +82,15 @@ There are implicit conversions from corresponding Scala types and back:
There is no type `js.Null`, because `scala.Null` can be used in its stead with
the appropriate semantics.

`isInstanceOf[T]` for `T` being `js.Number`, `js.Boolean`, `js.String`, or
`js.Undefined`, is supported and is implemented with a `typeof` test.

`isInstanceOf[T]` is supported for _classes_ inheriting from `js.Object`, e.g.,
`js.Date`, `js.Array[_]`, `js.Object` itself, and is implemented with an
`instanceof` test.

`isInstanceOf[T]` for `T` being `js.prim.Number`, `js.prim.Boolean`,
`js.prim.String`, or `js.prim.Undefined`, is supported and is
implemented with a `typeof` test. However, it should be avoided in
preference of `T` being `Double`, `Boolean`, `String` or `Unit`.

`isInstanceOf[T]` is not supported for any other `T` (i.e., traits) inheriting
from `js.Any`.
Consequently, pattern matching for such types is not supported either.
Expand Down Expand Up @@ -224,8 +233,11 @@ if the result will always be the same (e.g., `document`), and `def` when
subsequent accesses to the field might return a different value (e.g.,
`innerWidth`).

Use `Unit` instead of `js.Undefined` as result type of methods that do not
return any value.
Use Scala primitive types instead of types in `js.prim._`. Instead of
`js.prim.Number`, use `Int` where applicable (integral value, not
`NaN`, in signed 32-bit integer range). Otherwise `Double` should be
used (note that `Long` is opaque to JavaScript and therefore cannot be
used).

Calls to the `apply` method of an object `x` map to calling `x`, i.e., `x(...)`
instead of `x.apply(...)`.
Expand Down
41 changes: 31 additions & 10 deletions doc/export-to-javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,13 @@ title: Export Scala.js APIs to JavaScript
---
{% include JB/setup %}

**New in Scala.js v0.4**

By default, Scala.js classes, objects, methods and properties are not available
to JavaScript. Entities that have to be accessed from JavaScript must be
annotated explicitly as *exported*. The `@JSExport` annotation is the main way
to do this.

## A simple example

You have probably already seen two uses of `@JSExport` in the `Main` class of
the bootstrapping skeleton (or any other template of Scala.js application):

{% highlight scala %}
package example

Expand All @@ -39,9 +34,34 @@ HelloWorld().main();

Note the `()` when accessing the object, `HelloWorld` is a function.

This simple pair of `@JSExport` should be sufficient for most application, i.e.,
in cases you only want to get into the entry point of your app, and then live
in the Scala.js world.
You have probably already used an `@JSExport` without knowing it
through the `JSApp` trait in the `Main` class of the bootstrapping
skeleton (or any other template of Scala.js application). In fact, any
Scala.js application must export at least a class or an object and a
method in order to be invokable at all.

Most of the time, however, it is sufficient to just extend the `JSApp`
trait:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"In general" -> "Most of the time"? I believe the former means more "always" than "most of the time".


{% highlight scala %}
package example

import scala.scalajs.js
import js.annotation.JSExport

object HelloWorld extends js.JSApp {
def main(): Unit = {
println("Hello world!")
}
}
{% endhighlight %}

And call like this (see documentation about
`@JSExportDescendentObjects` below for internal workings):

{% highlight javascript %}
example.HelloWorld().main();
{% endhighlight %}

## Exporting top-level objects

Expand Down Expand Up @@ -249,8 +269,9 @@ objects of a given trait or class. You can use the
objects to be exported to their fully qualified name.

This feature is especially useful in conjunction with exported
abstract methods and is used by the test libraries of Scala.js. The
following is just an example, how the feature can be used:
abstract methods and is used by the test libraries of Scala.js and the
`scala.scalajs.js.JSApp` trait. The following is just an example, how
the feature can be used:

{% highlight scala %}
package foo.test
Expand Down
16 changes: 15 additions & 1 deletion doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ title: Documentation

## Get started

Get started with Scala.js by forking off our
Get started with Scala.js by following our [tutorial](./tutorial.html) or by forking off our
[barebone skeleton](https://github.com/sjrd/scala-js-example-app).

Alternatively, create a project with *custom naming* by using this [giter8 template](https://github.com/sebnozzi/scala-js.g8).
Expand All @@ -15,12 +15,26 @@ Alternatively, create a project with *custom naming* by using this [giter8 templ

* [Differences between the semantics of Scala and Scala.js](./semantics.html)
* [JavaScript interoperability](./js-interoperability.html)
* [Call JavaScript APIs from Scala.js](./calling-javascript.html)
* [Export Scala.js APIs to JavaScript](./export-to-javascript.html)
* [SBT plugin](./sbt-plugin.html)
* [Setup](./sbt/setup.html)
* [Compiling, Running, Linking, Optimizing](./sbt/run.html)
* [Depending on Libraries](./sbt/depending.html)
* [JavaScript Environments](./sbt/js-envs.html)
* [Cross-Building](./sbt/cross-building.html)
* [Scala.js Cookbook](./cookbook/)

## API

Generated Scaladocs are available here:

#### Scala.js 0.5.0
* [0.5.0 scalajs-library]({{ BASE_PATH }}/api/scalajs-library/0.5.0/)
* [0.5.0 scalajs-tools]({{ BASE_PATH }}/api/scalajs-tools/0.5.0/)
* [0.5.0 scalajs-test-bridge]({{ BASE_PATH }}/api/scalajs-test-bridge/0.5.0/)
* [0.5.0 scalajs-jasmine-test-framework]({{ BASE_PATH }}/api/scalajs-jasmine-test-framework/0.5.0/)

#### Scala.js 0.5.0-RC2
* [0.5.0-RC2 scalajs-library]({{ BASE_PATH }}/api/scalajs-library/0.5.0-RC2/)
* [0.5.0-RC2 scalajs-tools]({{ BASE_PATH }}/api/scalajs-tools/0.5.0-RC2/)
Expand Down
38 changes: 38 additions & 0 deletions doc/js-interoperability.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,41 @@ called from JavaScript code.

* [Call JavaScript APIs from Scala.js](calling-javascript.html)
* [Export Scala.js APIs to JavaScript](export-to-javascript.html)

## <a name="type-correspondance"></a> Type Correspondance
Some Scala types are directly mapped to corresponding underlying
JavaScript types. These correspondances can be used when calling
Scala.js code from JavaScript and when defining typed interfaces for
JavaScript code.

<table class="table table-bordered">
<thead>
<tr><th>Scala type</th><th>JavaScript type</th><th>Restrictions</th></tr>
</thead>
<tbody>
<tr><td>java.lang.String</td><td>string</td><td></tr></tr>
<tr><td>scala.Boolean</td><td>boolean</td><td></td></tr>
<tr><td>scala.Char</td><td><i>opaque</i></td><td></td></tr>
<tr><td>scala.Byte</td><td>number</td><td>integer, range (-128, 127)</td></tr>
<tr><td>scala.Short</td><td>number</td><td>integer, range (-32768, 32767)</td></tr>
<tr><td>scala.Int</td><td>number</td><td>integer, range (-2147483648, 2147483647)</td></tr>
<tr><td>scala.Long</td><td><i>opaque</i></td><td></td></tr>
<tr><td>scala.Float</td><td>number</td><td></td></tr>
<tr><td>scala.Double</td><td>number</td><td></td></tr>
<tr><td>scala.Unit</td><td>undefined</td><td></td></tr>
<tr><td>scala.Null</td><td>null</td><td></td></tr>
<tr><td>subtypes of js.Object</td><td><i>corresponding JavaScript
type</i></td><td>see <a href="calling-javascript.html">calling JavaScript guide</a></td></tr>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line or another line should say something about all the other types extending js.Object (not necessarily in the js package).

<tr>
<td>
other Scala classes<br />
<small>including value classes</small>
</td>
<td>
<i>opaque, except for exported methods</i><br />
<small>Note: <code>toString()</code> is always exported</small>
</td>
<td>see <a href="export-to-javascript.html">exporting Scala.js APIs to JavaScript</a></td>
</tr>
</tbody>
</table>
13 changes: 13 additions & 0 deletions doc/sbt-plugin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
layout: page
title: Scala.js sbt Plugin
---
{% include JB/setup %}

Scala.js comes with an sbt plugin that facilitates compiling, running and testing with Scala.js. For a quick start, have a look at our [bootstrapping skeleton](https://github.com/sjrd/scala-js-example-app).

* [Setup](./sbt/setup.html)
* [Compiling, Running, Linking, Optimizing](./sbt/run.html)
* [Depending on Libraries](./sbt/depending.html)
* [JavaScript Environments](./sbt/js-envs.html)
* [Cross-Building](./sbt/cross-building.html)
47 changes: 47 additions & 0 deletions doc/sbt/cross-building.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
layout: page
title: Cross-Building
---

Sometimes it is desirable to compile the same source code with Scala.js and Scala JVM. In order to do this, you need two different projects, one for Scala.js and one for Scala JVM and a folder with the shared source code. You then can tell sbt to use the shared source folder in addition to the normal source locations.

We give a simple example of how such a project, we call it `foo`, could look. You can find this project on [GitHub](https://github.com/scala-js/scalajs-cross-compile-example).

## Directory Structure

<project root>
+- foo-jvm
| +- src/main/scala
+- foo-js
| +- src/main/scala
+- foo-shared
+- src/main/scala

In `foo-shared/src/main/scala` are the shared source files. In `foo-{js|jvm}/src/main/scala` are the source files specific to the respective platform (these folders are optional).

## sbt Build File

Starting from sbt 0.13, you can write a multi-project build in a `.sbt` file. This is an example how your `build.sbt` could look like:

name := "Foo root project"

version := "0.1"

lazy val root = project.in(file(".")).aggregate()

lazy val fooJS = project.in(file("foo-js")).settings(scalaJSSettings: _*).settings(
name := "foo",
unmanagedSourceDirectories in Compile += root.base / "foo-shared" / "src" / "main" / "scala"
)

lazy val fooJVM = project.in(file("foo-jvm")).settings(
name := "foo",
unmanagedSourceDirectories in Compile += root.base / "foo-shared" / "src" / "main" / "scala"
)

You now have separate projects to compile towards Scala.js and Scala JVM. Note the same name given to both projects, this allows them to be published with corresponding artifact names:

- `foo_2.10-0.1-SNAPSHOT.jar`
- `foo_sjs0.5.0-RC2_2.10-0.1-SNAPSHOT.jar`

If you do not publish the artifacts, you may choose different names for the projects.
67 changes: 67 additions & 0 deletions doc/sbt/depending.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
layout: page
title: Depending on Libraries
---

## Depending on Scala.js libraries

To be able to use a Scala library in Scala.js, it has to be separately compiled for Scala.js. You then can add it to your library dependencies as follows:

libraryDependencies += "org.scala-lang.modules.scalajs" %%% "scalajs-dom" % "0.5"

Note the `%%%` (instead of the usual `%%`) which will add the current Scala.js version to the artifact name. This allows to

- Cross-publish libraries to different Scala.js versions
- Disambiguate Scala.js from Scala JVM libraries

Some Scala.js core libraries (such as the Scala.js library itself) do not need the `%%%` since their version number *is* the Scala.js version number itself.

## Depending on JavaScript libraries

Thanks to [WebJars](http://www.webjars.org/), you can easily fetch a JavaScript library like so:

libraryDependencies += "org.webjars" % "jquery" % "1.10.2"

This will fetch the required JAR containing jQuery. However, it will not include it once you run your JavaScript code, since there is no class-loading process for JavaScript.

The Scala.js sbt plugin has `jsDependencies` for this purpose. You can write:

jsDependencies += "org.webjars" % "jquery" % "1.10.2" / "jquery.js"

This will make your project depend on the respective WebJar and include a file named `jquery.js` in the said WebJar when your project is run or tested. We are trying to make the semantics of "include" to be as close as possible to writing:

<script type="text/javascript" src="..."></script>

However, sometimes this doesn't work when running with Node.js. If this happens to you, change to Phantom.js (see below on how to do that).

All `jsDependencies` and associated metadata (e.g. for ordering) are persisted in a file (called `JS_DEPENDENCIES`) and shipped with the artifact your project publishes. For example, if you depend on the `jasmine-test-framework` package for Scala.js (a thin wrapper around Jasmine), you do not need to explicitly depend or include `jasmine.js`; this mechanism does it for you.

### Scoping to a Configuration

You may scope `jsDependencies` on a given configuration, just like for normal `libraryDependencies`:

jsDependencies += "org.webjars" % "jquery" % "1.10.2" / "jquery.js" % "test"

### Dependency Ordering

Since JavaScript does not have a class loading mechanism, the order in which libraries are loaded may matter. If this is the case, you can specify a library's dependencies like so:

jsDependencies += "org.webjars" % "jasmine" % "1.3.1" / "jasmine-html.js" dependsOn "jasmine.js"

Note that the dependee must be declared as explicit dependency elsewhere, but not necessarily in this project (for example in a project the current project depends on).

### Local JavaScript Files

If you need to include JavaScript files which are provided in the resources of your project, use:

jsDependencies += ProvidedJS / "myJSLibrary.js"

This will look for `myJSLibrary.js` in the resources and include it. It is an error if it doesn't exist. You may use ordering and scoping if you need.

### Write a Dependency File

If you want all JavaScript dependencies to be concatenated to a single file (for easy inclusion into a HTML file for example), you can set:

skip in packageJSDependencies := false

in your project settings. The resulting file in the target folder will have the suffix `-jsdeps.js`.
Loading