Skip to content
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

Migrate to mdoc.js #741

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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 .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = 3.6.0
version = 3.6.1
runner.dialect = scala213source3
project.git = true
style = Scala.js
Expand Down
17 changes: 14 additions & 3 deletions api-reports/2_12.txt
Original file line number Diff line number Diff line change
Expand Up @@ -993,11 +993,11 @@ Clients[JT] def openWindow(url: String): js.Promise[WindowClient]
Clipboard[JT] def addEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], options: EventListenerOptions): Unit
Clipboard[JT] def addEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], useCapture: Boolean?): Unit
Clipboard[JT] def dispatchEvent(evt: Event): Boolean
Clipboard[JT] def read(): js.Promise[DataTransfer]
Clipboard[JT] def read(): js.Promise[js.Array[ClipboardItem]]
Clipboard[JT] def readText(): js.Promise[String]
Clipboard[JT] def removeEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], options: EventListenerOptions): Unit
Clipboard[JT] def removeEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], useCapture: Boolean?): Unit
Clipboard[JT] def write(data: DataTransfer): js.Promise[Unit]
Clipboard[JT] def write(data: js.Array[ClipboardItem]): js.Promise[Unit]
Clipboard[JT] def writeText(newClipText: String): js.Promise[Unit]
ClipboardEvent[JC] def bubbles: Boolean
ClipboardEvent[JC] def cancelBubble: Boolean
Expand All @@ -1019,6 +1019,10 @@ ClipboardEventInit[JT] var composed: js.UndefOr[Boolean]
ClipboardEventInit[JT] var data: js.UndefOr[String]
ClipboardEventInit[JT] var dataType: js.UndefOr[String]
ClipboardEventInit[JT] var scoped: js.UndefOr[Boolean]
ClipboardItem[JC] def getType(`type`: String): js.Promise[Blob]
ClipboardItem[JC] def presentationStyle: PresentationStyle
ClipboardItem[JC] def types: FrozenArray[String]
ClipboardItemOptions[JT] def presentationStyle: js.UndefOr[PresentationStyle]
CloseEvent[JT] def bubbles: Boolean
CloseEvent[JT] def cancelBubble: Boolean
CloseEvent[JT] def cancelable: Boolean
Expand Down Expand Up @@ -2017,6 +2021,8 @@ FrameType[SO] val auxiliary: FrameType
FrameType[SO] val nested: FrameType
FrameType[SO] val none: FrameType
FrameType[SO] val `top-level` = "top-level".asInstanceOf[FrameType]
FrozenArray[JT] @js.annotation.JSBracketAccess def apply(index: Int): T
FrozenArray[JT] val length: Int
FullscreenOptions[JT] var navigationUI: js.UndefOr[String]
GainNode[JT] def addEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], options: EventListenerOptions): Unit
GainNode[JT] def addEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], useCapture: Boolean?): Unit
Expand Down Expand Up @@ -16226,6 +16232,10 @@ PositionError[JT] def message: String
PositionOptions[JC] var enableHighAccuracy: Boolean
PositionOptions[JC] var maximumAge: Int
PositionOptions[JC] var timeout: Int
PresentationStyle[JT]
PresentationStyle[SO] val attachment: PresentationStyle
PresentationStyle[SO] val inline: PresentationStyle
PresentationStyle[SO] val unspecified: PresentationStyle
ProcessingInstruction[JC] def addEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], options: EventListenerOptions): Unit
ProcessingInstruction[JC] def addEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], useCapture: Boolean?): Unit
ProcessingInstruction[JC] def appendChild(newChild: Node): Node
Expand Down Expand Up @@ -25158,7 +25168,7 @@ StyleSheetList[JC] def item(index: Int): StyleSheet
StyleSheetList[JC] def length: Int
StyleSheetList[JC] @scala.scalajs.js.annotation.JSBracketAccess def update(index: Int, v: StyleSheet): Unit
SubtleCrypto[JT] def decrypt(algorithm: AlgorithmIdentifier, key: CryptoKey, data: BufferSource): js.Promise[js.Any]
SubtleCrypto[JT] def deriveBits(algorithm: AlgorithmIdentifier, baseKey: CryptoKey, length: Double): js.Promise[js.Any]
SubtleCrypto[JT] def deriveBits(algorithm: AlgorithmIdentifier, baseKey: CryptoKey, length: Double): js.Promise[ArrayBuffer]
SubtleCrypto[JT] def deriveKey(algorithm: AlgorithmIdentifier, baseKey: CryptoKey, derivedKeyType: KeyAlgorithmIdentifier, extractable: Boolean, keyUsages: js.Array[KeyUsage]): js.Promise[js.Any]
SubtleCrypto[JT] def digest(algorithm: HashAlgorithmIdentifier, data: BufferSource): js.Promise[js.Any]
SubtleCrypto[JT] def encrypt(algorithm: AlgorithmIdentifier, key: CryptoKey, data: BufferSource): js.Promise[js.Any]
Expand Down Expand Up @@ -26946,6 +26956,7 @@ package[SO] type BufferSource = ArrayBufferView | ArrayBuffer
package[SO] type ByteString = String
package[SO] type ClientRect = DOMRect (@deprecated in 2.0.0)
package[SO] type ClientRectList = DOMRectList (@deprecated in 2.0.0)
package[SO] type ClipboardItemData = js.Promise[String | Blob]
package[SO] type HashAlgorithmIdentifier = HashAlgorithm | String
package[SO] type HeadersInit = Headers | Sequence[Sequence[ByteString]] | OpenEndedDictionary[ByteString]
package[SO] type IDBKey = Any
Expand Down
17 changes: 14 additions & 3 deletions api-reports/2_13.txt
Original file line number Diff line number Diff line change
Expand Up @@ -993,11 +993,11 @@ Clients[JT] def openWindow(url: String): js.Promise[WindowClient]
Clipboard[JT] def addEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], options: EventListenerOptions): Unit
Clipboard[JT] def addEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], useCapture: Boolean?): Unit
Clipboard[JT] def dispatchEvent(evt: Event): Boolean
Clipboard[JT] def read(): js.Promise[DataTransfer]
Clipboard[JT] def read(): js.Promise[js.Array[ClipboardItem]]
Clipboard[JT] def readText(): js.Promise[String]
Clipboard[JT] def removeEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], options: EventListenerOptions): Unit
Clipboard[JT] def removeEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], useCapture: Boolean?): Unit
Clipboard[JT] def write(data: DataTransfer): js.Promise[Unit]
Clipboard[JT] def write(data: js.Array[ClipboardItem]): js.Promise[Unit]
Clipboard[JT] def writeText(newClipText: String): js.Promise[Unit]
ClipboardEvent[JC] def bubbles: Boolean
ClipboardEvent[JC] def cancelBubble: Boolean
Expand All @@ -1019,6 +1019,10 @@ ClipboardEventInit[JT] var composed: js.UndefOr[Boolean]
ClipboardEventInit[JT] var data: js.UndefOr[String]
ClipboardEventInit[JT] var dataType: js.UndefOr[String]
ClipboardEventInit[JT] var scoped: js.UndefOr[Boolean]
ClipboardItem[JC] def getType(`type`: String): js.Promise[Blob]
ClipboardItem[JC] def presentationStyle: PresentationStyle
ClipboardItem[JC] def types: FrozenArray[String]
ClipboardItemOptions[JT] def presentationStyle: js.UndefOr[PresentationStyle]
CloseEvent[JT] def bubbles: Boolean
CloseEvent[JT] def cancelBubble: Boolean
CloseEvent[JT] def cancelable: Boolean
Expand Down Expand Up @@ -2017,6 +2021,8 @@ FrameType[SO] val auxiliary: FrameType
FrameType[SO] val nested: FrameType
FrameType[SO] val none: FrameType
FrameType[SO] val `top-level` = "top-level".asInstanceOf[FrameType]
FrozenArray[JT] @js.annotation.JSBracketAccess def apply(index: Int): T
FrozenArray[JT] val length: Int
FullscreenOptions[JT] var navigationUI: js.UndefOr[String]
GainNode[JT] def addEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], options: EventListenerOptions): Unit
GainNode[JT] def addEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], useCapture: Boolean?): Unit
Expand Down Expand Up @@ -16226,6 +16232,10 @@ PositionError[JT] def message: String
PositionOptions[JC] var enableHighAccuracy: Boolean
PositionOptions[JC] var maximumAge: Int
PositionOptions[JC] var timeout: Int
PresentationStyle[JT]
PresentationStyle[SO] val attachment: PresentationStyle
PresentationStyle[SO] val inline: PresentationStyle
PresentationStyle[SO] val unspecified: PresentationStyle
ProcessingInstruction[JC] def addEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], options: EventListenerOptions): Unit
ProcessingInstruction[JC] def addEventListener[T <: Event](`type`: String, listener: js.Function1[T, _], useCapture: Boolean?): Unit
ProcessingInstruction[JC] def appendChild(newChild: Node): Node
Expand Down Expand Up @@ -25158,7 +25168,7 @@ StyleSheetList[JC] def item(index: Int): StyleSheet
StyleSheetList[JC] def length: Int
StyleSheetList[JC] @scala.scalajs.js.annotation.JSBracketAccess def update(index: Int, v: StyleSheet): Unit
SubtleCrypto[JT] def decrypt(algorithm: AlgorithmIdentifier, key: CryptoKey, data: BufferSource): js.Promise[js.Any]
SubtleCrypto[JT] def deriveBits(algorithm: AlgorithmIdentifier, baseKey: CryptoKey, length: Double): js.Promise[js.Any]
SubtleCrypto[JT] def deriveBits(algorithm: AlgorithmIdentifier, baseKey: CryptoKey, length: Double): js.Promise[ArrayBuffer]
SubtleCrypto[JT] def deriveKey(algorithm: AlgorithmIdentifier, baseKey: CryptoKey, derivedKeyType: KeyAlgorithmIdentifier, extractable: Boolean, keyUsages: js.Array[KeyUsage]): js.Promise[js.Any]
SubtleCrypto[JT] def digest(algorithm: HashAlgorithmIdentifier, data: BufferSource): js.Promise[js.Any]
SubtleCrypto[JT] def encrypt(algorithm: AlgorithmIdentifier, key: CryptoKey, data: BufferSource): js.Promise[js.Any]
Expand Down Expand Up @@ -26946,6 +26956,7 @@ package[SO] type BufferSource = ArrayBufferView | ArrayBuffer
package[SO] type ByteString = String
package[SO] type ClientRect = DOMRect (@deprecated in 2.0.0)
package[SO] type ClientRectList = DOMRectList (@deprecated in 2.0.0)
package[SO] type ClipboardItemData = js.Promise[String | Blob]
package[SO] type HashAlgorithmIdentifier = HashAlgorithm | String
package[SO] type HeadersInit = Headers | Sequence[Sequence[ByteString]] | OpenEndedDictionary[ByteString]
package[SO] type IDBKey = Any
Expand Down
3 changes: 2 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ val testsChrome = Build.testsChrome
val testsFirefox = Build.testsFirefox
val testsNodeJsdom = Build.testsNodeJsdom
val example = Build.example
val readme = Build.readme
val jsdocs = Build.jsdocs
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!
16 changes: 16 additions & 0 deletions dom/src/main/scala-2/org/scalajs/dom/PresentationStyle.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.scalajs.dom

import scala.scalajs.js

/**
* Helps distinguish whether apps "pasting" a clipboard item should insert the contents of an appropriate representation inline at the point of paste or if it should be treated as an attachment.
* See [[https://w3c.github.io/clipboard-apis/#enumdef-presentationstyle PresentationStyle enum]]
*/
@js.native
sealed trait PresentationStyle extends js.Any

object PresentationStyle{
val unspecified: PresentationStyle = "unspecified".asInstanceOf[PresentationStyle]
val inline: PresentationStyle = "inline".asInstanceOf[PresentationStyle]
val attachment: PresentationStyle = "attachment".asInstanceOf[PresentationStyle]
}
15 changes: 15 additions & 0 deletions dom/src/main/scala-3/org/scalajs/dom/PresentationStyle.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.scalajs.dom

import scala.scalajs.js

/**
* Helps distinguish whether apps "pasting" a clipboard item should insert the contents of an appropriate representation inline at the point of paste or if it should be treated as an attachment.
* See [[https://w3c.github.io/clipboard-apis/#enumdef-presentationstyle PresentationStyle enum]]
*/
opaque type PresentationStyle <: String = String

object PresentationStyle {
val unspecified: PresentationStyle = "unspecified"
val inline: PresentationStyle = "inline"
val attachment: PresentationStyle = "attachment"
}
4 changes: 1 addition & 3 deletions dom/src/main/scala/org/scalajs/dom/Body.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ trait Body extends js.Object {
/** Takes a Response stream and reads it to completion. It returns a promise that resolves with a FormData object. */
def formData(): js.Promise[FormData] = js.native

/** Takes a Response stream and reads it to completion. It returns a promise that resolves with a JSON object. //todo:
* define the JSON type, and return a Promise[JSON] as per spec
*/
/** Takes a Response stream and reads it to completion. It returns a promise that resolves with a JSON object. */
def json(): js.Promise[js.Any] = js.native

/** Takes a Response stream and reads it to completion. It returns a promise that resolves with a USVString (text). */
Expand Down
4 changes: 2 additions & 2 deletions dom/src/main/scala/org/scalajs/dom/Clipboard.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ trait Clipboard extends EventTarget {
*
* To read from the clipboard, you must first have the "clipboard-read" permission.
*/
def read(): js.Promise[DataTransfer] = js.native
def read(): js.Promise[js.Array[ClipboardItem]] = js.native

/** The readText() method returns a Promise which resolves with a copy of the textual contents of the system
* clipboard.
Expand All @@ -38,7 +38,7 @@ trait Clipboard extends EventTarget {
* Before you can write to the clipboard, you need to use the Permissions API to get the "clipboard-write"
* permission.
*/
def write(data: DataTransfer): js.Promise[Unit] = js.native
def write(data: js.Array[ClipboardItem]): js.Promise[Unit] = js.native

/** The writeText() method writes the specified text string to the system clipboard. */
def writeText(newClipText: String): js.Promise[Unit] = js.native
Expand Down
Loading