Skip to content

Replace docs with mdoc #766

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ val testsChrome = Build.testsChrome
val testsFirefox = Build.testsFirefox
val testsNodeJsdom = Build.testsNodeJsdom
val example = Build.example
val readme = Build.readme
val docs = Build.docs
183 changes: 183 additions & 0 deletions docs/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
## scala-js-dom

---

#### Statically typed DOM API for Scala.js

Scala-js-dom provides a nice statically typed interface to the DOM such that it can be called from Scala code without resorting to `js.Dynamic`.
All javascript globals functions, singletons and classes are members of the `org.scalajs.dom`,
`org.scalajs.dom.html`, `org.scalajs.dom.svg`, etc. packages.

For example:

```scala
import org.scalajs.dom

def main() = dom.window.alert("Hi from scala-js-dom!")
```

## Usage

Add the following to your sbt build definition:

```scala
libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "@VERSION@"
```

then enjoy the types available in org.scalajs.dom. scalajs-dom @VERSION@ is built and published for Scala.js 1.5+ with Scala 2.11, 2.12, 2.13, and 3.0+.

To begin with, scala-js-dom organizes the full-list of DOM APIs into a number of buckets:

- dom.html: HTML element APIs
- dom.svg: SVG element APIs
- dom.idb: IndexedDB APIs
- dom.css: CSS APIs
- dom: Miscellanious, unclassified APIs

Most names have been shortened from names of the raw browser APIs, since the namespacing avoids collisions. By convention these types are imported qualified: e.g. as `html.Canvas` instead of directly as `Canvas`. There is also the `dom.raw` namespace which contains everything with their full, un-shortened name.

## Examples

You can start using the bindings using the following import:

```scala mdoc:js:shared
import org.scalajs.dom._
```

### Appending a child to a `Node`

```scala mdoc:js:shared
def appendElement(div: html.Div): Unit = {
val child = document.createElement("div")
child.textContent = "I can add elements to DOM elements!"
div.appendChild(child)
}
```

```scala mdoc:js:invisible
<div id="outer-container"></div>
<button id="demo1" class="button-run">Run</button>
---
document.getElementById("demo1").addEventListener("click", (ev: Event) => {
appendElement(document.getElementById("outer-container").asInstanceOf[html.Div])
})
```

### Add an EventListener for `onmousemove`

```scala mdoc:js
def showOnMouseCoordinates(pre: html.Pre): Unit = {
pre.onmousemove = (ev: MouseEvent) =>
pre.textContent = s"""
|ev.clientX: ${ev.clientX}
|ev.clientY: ${ev.clientY}
|ev.pageX: ${ev.pageX}
|ev.screenX: ${ev.screenX}
|ev.screenY: ${ev.screenY}
""".stripMargin
}
```

### Storing an item in `localStorage`

```scala mdoc:js
def storeInputInLocalStorage(input: html.Input, box: html.Div) = {
val key = "myKey"
input.value = window.localStorage.getItem(key)

input.onkeyup = { (e: Event) =>
window.localStorage.setItem(
key, input.value
)

box.textContent = s"Saved: ${input.value} to local storage!"
}
}
```

### Using `Canvas` to draw

```scala mdoc:js
type Context2D = CanvasRenderingContext2D

def drawCuteSmiley(canvas: html.Canvas) = {
val context = canvas.getContext("2d").asInstanceOf[Context2D]

val size = 300
canvas.width = size
canvas.height = size

context.strokeStyle = "red"
context.lineWidth = 3
context.beginPath()
context.moveTo(size/3, 0)
context.lineTo(size/3, size/3)
context.moveTo(size*2/3, 0)
context.lineTo(size*2/3, size/3)
context.moveTo(size, size/2)
context.arc(size/2, size/2, size/2, 0, 3.14)

context.stroke()
}
```

### Using `Fetch` to make API calls in the browser

```scala mdoc:js
import scala.concurrent.ExecutionContext.Implicits.global

def fetchBoredApi(element: html.Pre) = {
val url =
"https://www.boredapi.com/api/activity"

val responseText = for {
response <- fetch(url).toFuture
text <- response.text().toFuture
} yield {
text
}

for (text <- responseText)
element.textContent = text
}
```

### Using Websockets

```scala mdoc:js
// TODO: currently crashes with an error
// def echoWebSocket(input: html.Input, pre: html.Pre) = {
// val echo = "wss://echo.websocket.org"
// val socket = new WebSocket(echo)

// socket.onmessage = {
// (e: MessageEvent) =>
// pre.textContent +=
// e.data.toString
// }

// socket.onopen = { (e: Event) =>
// input.onkeyup = { (e: Event) =>
// socket.send(input.value)
// }
// }
// }
```

### Styling an HTML element

```scala mdoc:js
def changeColor(div: html.Div) = {
val colors = Seq("red", "green", "blue")

val index = util.Random.nextInt(colors.length)

div.style.color = colors(index)
}
```

## Contributing

The DOM API is always evolving, and `scala-js-dom` tries to provide a thin-but-idiomatic Scala interface to modern browser APIs, without breaking the spec.

If you see something that you think can be improved, feel free to send a pull request. See our [Contributing Guide](https://github.com/scala-js/scala-js-dom/blob/main/CONTRIBUTING.md) for a detailed overview for starting hacking on `scala-js-dom` and making a PR!
3 changes: 2 additions & 1 deletion prePR.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ ThisBuild / prePR_nonCross := Def.sequential(

Def.taskDyn {
if (scalaVersion.value.startsWith("2.12."))
Def.task[Unit]((readme / Compile / compile).value)
// TODO should this really be docs / Compile?
Copy link
Member

Choose a reason for hiding this comment

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

TODO?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I actually don't know if the current docs / Compile / compile is the right command to run during prePR.
@armanbilge does:

      Def.task[Unit]((docs / Compile / compile).value)

work fine here?

Copy link
Member

Choose a reason for hiding this comment

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

I need to take another look at this. I was hoping we could decide how we are deploying the site so we can figure out what to do with the build :)

Def.task[Unit]((docs / Compile / compile).value)
else
Def.task(())
},
Expand Down
30 changes: 17 additions & 13 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import scalafix.sbt.ScalafixPlugin.autoImport._
import scalatex.ScalatexReadme
import Dependencies._
import Lib._
import mdoc.MdocPlugin
import sbtdynver.DynVerPlugin.autoImport.previousStableVersion
import mdoc.MdocPlugin.autoImport._

object Build {

Expand All @@ -37,7 +40,6 @@ object Build {
testsFirefox,
testsNodeJsdom,
example,
// readme, // This is a Scala 2.12 only module
)

lazy val dom = project
Expand Down Expand Up @@ -141,18 +143,20 @@ object Build {
.enablePlugins(ScalaJSPlugin)
.configure(commonSettings, crossScala, preventPublication)

lazy val readme =
ScalatexReadme(
projectId = "readme",
wd = file(""),
url = "https://github.com/scala-js/scala-js-dom/tree/main",
source = "Index",
autoResources = Seq("example-opt.js"),
)
.configure(commonSettings, preventPublication)
lazy val jsdocs = project
.in(file("mdocs-js"))
.dependsOn(dom)
.enablePlugins(ScalaJSPlugin)
.configure(commonSettings, crossScala, preventPublication)

lazy val docs = project
.in(file("mdocs"))
.settings(
scalaVersion := Ver.scala212,
Compile / resources += (example / Compile / fullOptJS).value.data,
mdocJS := Some(jsdocs),
mdocVariables := Map(
"VERSION" -> previousStableVersion.value.getOrElse("2.3.0")
)
)

.enablePlugins(MdocPlugin)
.configure(commonSettings, crossScala, preventPublication)
}
11 changes: 6 additions & 5 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
libraryDependencies += "org.scala-js" %% "scalajs-env-jsdom-nodejs" % "1.1.0"
libraryDependencies += "org.scala-js" %% "scalajs-env-selenium" % "1.1.1"

addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.10.4")
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.10.4")
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0")
addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.11")
addSbtPlugin("com.lihaoyi" % "scalatex-sbt-plugin" % "0.3.11")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.7.1")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.0")
addSbtPlugin("com.lihaoyi" % "scalatex-sbt-plugin" % "0.3.11")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.7.1")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.0")
addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.3.6")
Loading