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

https://github.com/colonelpanic8/dominion-hud


https://github.com/colonelpanic8/dominion-hud

Last synced: 2 months ago
JSON representation

Awesome Lists containing this project

README

          

# chromex-sample [![GitHub license](https://img.shields.io/github/license/binaryage/chromex-sample.svg)](license.txt)

### An example extension using Chromex library

This project acts as a code example for [chromex library](https://github.com/binaryage/chromex) but also as a skeleton
with project configuration following best practices. We recommend to use it as a starting point when starting development
of your own extension.

#### **chromex-sample** has a minimalist **background page**, **popup button** and **content script**:

* background page listens for connections from popup buttons and content scripts (there can be multiple of them)
* popup button connects to the background page and sends a simple "HELLO" message after connection
* content script connects to the background page and sends a simple "HELLO" message after connection
* content script does a simple page analysis upon launch (it counts number of script tags) and sends an info message to the background page
* background page listens to tab creation events and notifies all connected clients about new tabs being created

#### **chromex-sample** project has following configuration:

* uses [leiningen](http://leiningen.org) + [lein-cljsbuild](https://github.com/emezeske/lein-cljsbuild)
* integrates [cljs-devtools](https://github.com/binaryage/cljs-devtools)
* integrates [figwheel](https://github.com/bhauman/lein-figwheel) (for background page and popup buttons)
* under `:unpacked` profile (development)
* background page and popup button
* compiles with `optimizations :none`
* namespaces are included as individual files and source maps work as expected
* figwheel works
* content script
* due to [security restrictions](https://github.com/binaryage/chromex-sample/issues/2), content script has to be provided as a single file
* compiles with `:optimizations :whitespace` and `:pretty-print true`
* figwheel cannot be used in this context (eval is not allowed)
* under `:release` profile
* background page, popup button and content script compile with `optimizations :advanced`
* elides asserts
* no figwheel support
* no cljs-devtools support
* `lein package` task is provided for building an extension package for release

### Local setup

#### Extension development

We assume you are familiar with ClojureScript tooling and you have your machine in a good shape running recent versions of
java, maven, leiningen, etc.

* clone this repo somewhere:
```bash
git clone https://github.com/binaryage/chromex-sample.git
cd chromex-sample
```
* chromex sample is gets built into `resources/unpacked/compiled` folder.

In one terminal session run (will build background and popup pages using figwheel):
```bash
lein fig
```
In a second terminal session run (will auto-build content-script):
```bash
lein content
```
* use latest Chrome Canary with [Custom Formatters](https://github.com/binaryage/cljs-devtools#enable-custom-formatters-in-your-chrome-canary) enabled
* In Chrome Canary, open `chrome://extensions` and add `resources/unpacked` via "Load unpacked extension..."

##### Debugging

Chrome extension development is more complex than regular ClojureScript front-end
work. You are writing (and debugging) multiple parallel communicating processes: your
background page, your popup, and all the browser pages running your content script.

Amazingly, the ClojureScript tooling and Figwheel live coding remain very usable in this
environment. But, you need to be aware of a few things, particularly in regard to
compiler warnings:

Most warnings do not appear in the repls. Figwheel intercepts them for display in the
browser. Warning will appear in the Chrome console and, when possible, as an overlay in
the browser window. But, the exact behavior depends upon which part of your code has the
error:

_Content script_: Warnings and errors will appear in the repl running `lein content`.

_popup_: Chrome normally closes the popup anytime focus leaves Chrome. So, if you are
working in your editor, the popup is closed and you will not see any error messages
anywhere. This can be very frustrating but is easy to fix. When you first open the
popup, right click on its icon and select `Inspect popup`. This opens the Chrome
inspector/console and keeps the popup open while the inspector remains open. Any errrors
will appear in both the console and as the Figwheel overlay in your popup window. Also,
of course, this gives you niceties of Figwheel live coding. Your changes will appear
immediately, with no need to close and reopen the popup.

_background_: The background code is running under Figwheel, so no messages will appear
in the repl. It also has no visibile window, so no Figwheel overlay can appear. You will
only see warnings in the Chrome console. You can open the inspector/console from
`chrome://extensions`. Under your extension, click on the `Inspect Views` line.

In summary, effective live debugging requires up to five open windows on your screen:
- Your editor;
- The shell running `lein content`, if you are making changes to content script code;
- The web browser, with open popup and/or content page;
- A Chrome inspector console, watching the background page; and
- A Chrome inspector console, watching the popup page.

#### Extension packaging

[Leiningen project](project.clj) has defined "release" profile for compilation in advanced mode. Run:
```bash
lein release
```

This will build an optimized build into [resources/release](resources/release). You can add this folder via "Load unpacked extension..."
to test it.

When satisfied, you can run:
```bash
lein package
```

This will create a folder `releases/chromex-sample-0.1.0` where 0.1.0 will be current version from [project.clj](project.clj).
This folder will contain only files meant to be packaged.

Finally you can use Chrome's "Pack extension" tool to prepare the final package (.crx and .pem files).

### Code discussion

Before reading the code below you should get familiar with [Chrome Extension System architecture](https://developer.chrome.com/extensions/overview#arch).

#### Popup page

Let's start with [popup button code](src/popup/chromex_sample/popup/core.cljs):

```clojure
; -- a message loop -------------------------------------------------------------------------------

(defn process-message! [message]
(log "POPUP: got message:" message))

(defn run-message-loop! [message-channel]
(log "POPUP: starting message loop...")
(go-loop []
(when-some [message (clj` and `clj->js` would come handy at many places.

##### Message loop

It is worth noting that core.async channel [returns `nil` when closed](https://clojure.github.io/core.async/#clojure.core.async/