Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/lucidd/scala-js-chrome

ScalaJS bindings for Chrome Extention/App and ChromeOS APIs
https://github.com/lucidd/scala-js-chrome

chrome-api chrome-apps chrome-extension sbt scala scalajs

Last synced: 4 days ago
JSON representation

ScalaJS bindings for Chrome Extention/App and ChromeOS APIs

Awesome Lists containing this project

README

        

# Chrome for Scala.js [![Build Status](https://travis-ci.org/lucidd/scala-js-chrome.svg?branch=master)](https://travis-ci.org/lucidd/scala-js-chrome) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/lucidd/scala-js-chrome?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Latest version](https://index.scala-lang.org/lucidd/scala-js-chrome/scala-js-chrome/latest.svg?color=orange)](https://index.scala-lang.org/lucidd/scala-js-chrome/scala-js-chrome) [![Javadocs](https://www.javadoc.io/badge/net.lullabyte/scala-js-chrome_sjs0.6_2.12.svg)](https://www.javadoc.io/doc/net.lullabyte/scala-js-chrome_sjs0.6_2.12)

The goal of this project is to provide an easy and typesafe way to create Chrome
apps and extensions in Scala using the [Scala.js](https://www.scala-js.org/) project.

## Chrome API bindings

The bindings provide access to the Chrome app and extension APIs. There are two
levels for each API. One that provides the raw JavaScript bindings and a second
one which wraps the raw API in a more Scala idiomatic way.

The package structure is similar to the original JavaScript API.

```javascript
// original JavaScript
chrome.system.cpu.getInfo(function(info){
if (chrome.runtime.lastError === undefined) {
console.log(info);
} else {
console.log("ohoh something went wrong!");
}
});
```

```scala
// raw bindings
chrome.system.cpu.bindings.CPU.getInfo((info: CPUInfo) => {
if (chrome.runtime.bindings.Runtime.lastError.isEmpty) {
println(info)
} else {
println("ohoh something went wrong!")
}
})

// Scala idiomatic way using Future
chrome.system.cpu.CPU.getInfo.onComplete {
case Success(info) => println(info)
case Failure(error) => println("ohoh something went wrong!")
}
```

The Scala idiomatic binding provides the following general changes:

- Futures instead of callbacks
- Error handling using types like `Future` / `Try` instead of global error
variable.
- Using `Option` for things that may or may not be defined.

## SBT Plugin

The job of the SBT plugin is to help with common tasks for developing Chrome
apps/extensions. It also provides a way to configure your app/extension in your
SBT file and automatically generate the manifest file.

- `chromePackage` will create a ZIP file you can upload to the Chrome Web Store.
- `chromeUnpackedOpt` (or `chromeUnpackedFast`) will build your projects with (or without) optimizations enabled. The
output will be in `target/chrome/unpacked-opt` (or `target/chrome/unpacked-fast`) and can be loaded by Chrome as an
unpacked extension/app.

## Getting Started

Add this to your `project/plugins.sbt`:

```scala
addSbtPlugin("net.lullabyte" % "sbt-chrome-plugin" % "0.5.0")
```

Add this to your project dependencies:

```scala
"net.lullabyte" %%% "scala-js-chrome" % "0.5.0"
```

### with [scalajs-bundler](https://scalacenter.github.io/scalajs-bundler/)
to use the `-f{ast,ull}opt-bundle.js` generated by [scalajs-bundler](https://scalacenter.github.io/scalajs-bundler) add the following to your `build.sbt`:

```scala
fastOptJsLib := Attributed.blank((webpack in (Compile, fastOptJS)).value.head)
fullOptJsLib := Attributed.blank((webpack in (Compile, fullOptJS)).value.head)
```

_NOTE:_ if code seems to be executing duplicate times unintentionally, try removing these lines from the project's `build.sbt`

```scala
scalaJSUseMainModuleInitializer := true
scalaJSUseMainModuleInitializer in Test := false
```

### Creating a basic Window

```scala
import chrome.app.runtime.bindings.LaunchData
import chrome.app.window.Window
import utils.ChromeApp

import scalajs.concurrent.JSExecutionContext.Implicits.queue

object ChromeAppExample extends ChromeApp {

override def onLaunched(launchData: LaunchData): Unit = {
println("hello world from scala!")
Window.create("assets/html/App.html").foreach { window =>
/**
Access to the document of the newly created window.
From here you can change the HTML of the window with whatever
library you want to use.
*/
window.contentWindow.document
}
}

}
```

For a more complete example see [chrome-system-monitor](https://github.com/lucidd/chrome-system-monitor)
and [scala-js-chrome examples](https://github.com/lucidd/scala-js-chrome/tree/master/examples).

### UI Libraries

There are already multiple libraries to manipulate HTML and build your UI
available for Scala.js:

- [scala-js-dom](https://github.com/scala-js/scala-js-dom) For simple dom access
- [scalatags](https://github.com/lihaoyi/scalatags) Scala DSL for creating HTML
- [scalajs-react](https://github.com/japgolly/scalajs-react) Bindings for using react.js
- [scalacss](https://github.com/japgolly/scalacss) Typesafe way to write CSS
with Scala
- [Binding.scala](https://github.com/ThoughtWorksInc/Binding.scala) Reactive data-binding for Scala

### Known Issues

In Chrome apps and extensions there are multiple places where you can run
JavaScript. Normally you split your logic into different files and load them into
whatever context they need to run. Since Scala.js compiles your whole project
into one big file all contexts need to load this big file with all the logic
even if they only need a small subset. This can cause your app you use more
memory then it need to. In some cases this can be worked around for example the
a background page can manipulate the DOM of an App window so you don't need any
JavaScript at all in the window itself.