gorhill/uBlock — pull request #360 by Deathamns (2014-11-09 19:46:06+00:00)
Title: Portability

## Main goals
- Encapsulate extension APIs into a common API
- Support Safari
- Provide a build script for packaging extension files

## Structure

```
├─ dist/
│ └─ build # created when running the build script
│ └─ #.#.#.# # [version number] contains the built files
├─ doc/ # extension documentation
├─ meta/ # configuration and vendor specific files
│ ├─ crx/ # Chromium related files
│ ├─ safariextz/ # Safari related files
│ ├─ xpi/ # Firefox related files
│ └─ config.json # extension metadata (name, version, author...)
├─ src/ # source code
├─ tmp/ # temp directory, exists when the building is in progress
├─ tools/ # build scripts
└─ other files... # README, LICENSE...
```

## vendor API (vAPI)

The following files are responsible for the extension API encapsulation.

`/src/js/vapi-appifo.js` contains some common informations about the extension (like name, version string, homepage). It can be included where it's needed.
The reason for this is that not every browser provides an easy way to access these informations (Chrome does, Safari doesn't, Firefox gives an asynchronous method).
The content of this file is automatically updated when building.

`/src/js/vapi-background.js` included only in the background process.
It encloses the "privileged" APIs (like net request, tabs), that can run only in the background process.

`/src/js/vapi-common.js` it can be included in background process and extension pages (e.g., settings or pop-up).
Hold common APIs that could be used in both places (i18n API for example).

`/src/js/vapi-client.js` this also holds common APIs, but it can be included into extension pages and as content-scripts.
Currently it handles messaging, and contains extra code for specific vendors (if needed - see Safari).

Note that this API is not an extensive framework, only implements APIs which are needed for the extension to work properly.

The files contain all the vendor specific code. Which will run is determined by simple browser detection, but when building, only the correct code pieces are included into the corresponding extension files.

Basically these are the only js files which are different across browsers (if we don't count the extra files for Firefox (2) and Safari (1)).

## Metadata

These informations are used when building.

In order to keep extension data in one place, instead of updating all the vendor specific files (`manifest.json`, `Info.plist`...), the `/meta/config.json` keeps these common informations (such as name, version, author...), also contains vendor specific informations (extension IDs, path to private key which is used when building).

## Installing

The source code can be found under the `src` directory, and since all the manifest files and locales are not cleared when building (intentional), the extension can be installed for all browser from this directory without building or configuring anything first.

### Chromium based browsers
Go to the Extensions page (`chrome://extensions`), and drag n' drop the `src` folder onto the browser window.

### Safari
First you need to create a developer account and request a certificate from Apple, which you have to install on your machine. [More info](https://github.com/Rob--W/extension-dev-tools/tree/master/safari#certificate).

After you have your certificate installed...

Create a link named `uBlock.safariextension` for the `src` directory, open the Extension Builder in Safari, click Add Extension, and select the created link.

In Windows a Directory Junction needs to be created:
```
mklink /H /D /J uBlock.safariextension src
```

### Firefox
Create a proxy file named as the extension ID with the absolute path to the `src` directory as its content, and put it into `Firefox's profile folder/extensions/`.

To find out where the profile folder is, go to `about:support` and click the `Show folder` button in the **Profile folder** row.

So, basically:
```
$ cd src
$ mkdir -p /path/to/profile/folder/extensions
$ pwd > $_/{extension-id}
```

## Building (optional)

### Dependecy
- [Python3](https://www.python.org/downloads/)
- Unix enviroment or [cygwin](http://cygwin.com/install.html) for Windows with the following commands available
- 7z (Chrome, Firefox)
- openssl (Chrome)
- [xar](http://mackyle.github.io/xar/) (packaging for Safari)

Safari needs a few extra steps first, which are listed [here](https://github.com/Rob--W/extension-dev-tools/tree/master/safari#building-automated-linuxmac) (step 1,2,3).

---

The building will:
- update manifest files with the data from `meta/config.json`
- generate and copy necessary files for specific browser (e.g., locales)
- separate browser specific code from vapi-*.js files
- create update-files
- pack the code into usable extension files

The result files are placed into `/dist/build/#.#.#.# (version)` folder. If the same folder already exists, it will be removed first with its content.

To build everything, run the following command:
```
$ python tools/build.py
```

To refresh only the language and manifest files (note the optional `meta` argument):
```
$ python tools/build.py meta
```