Move to a Web Extension only. Fixes #1005
2
.gitignore
vendored
|
@ -8,4 +8,4 @@ README.html
|
|||
.env
|
||||
addon.env
|
||||
|
||||
webextension/web-ext-artifacts/*
|
||||
src/web-ext-artifacts/*
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
"extends": "stylelint-config-standard",
|
||||
|
||||
"ignoreFiles": ["webextension/css/*.min.css"],
|
||||
"ignoreFiles": ["src/css/*.min.css"],
|
||||
|
||||
"rules": {
|
||||
"declaration-block-no-duplicate-properties": true,
|
||||
|
|
64
README.md
|
@ -1,12 +1,9 @@
|
|||
# Multi-Account Containers
|
||||
|
||||
|
||||
The Firefox Multi-Account Containers extension lets you carve out a separate box for each of your online lives – no more opening a different browser just to check your work email! [Learn More Here](https://blog.mozilla.org/firefox/introducing-firefox-multi-account-containers/)
|
||||
|
||||
[Available on addons.mozilla.org](https://addons.mozilla.org/en-GB/firefox/addon/multi-account-containers/)
|
||||
|
||||
**Note:** Firefox 57 + 58 users should Install from our [latest GitHub Release](https://github.com/mozilla/testpilot-containers/releases/latest)
|
||||
|
||||
For more info, see:
|
||||
|
||||
* [Test Pilot Product Hypothesis Document](https://docs.google.com/document/d/1WQdHTVXROk7dYkSFluc6_hS44tqZjIrG9I-uPyzevE8/edit#)
|
||||
|
@ -16,67 +13,13 @@ For more info, see:
|
|||
## Requirements
|
||||
|
||||
* node 7+ (for jpm)
|
||||
* Firefox 53+
|
||||
* Firefox 57+
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
### Web Extension Development
|
||||
|
||||
Since Firefox 57, this extension can now be run without any of the legacy components that were previously needed.
|
||||
|
||||
1. Install web-ext with npm
|
||||
2. cd webextension; web-ext run -f Nightly
|
||||
|
||||
This will work in other builds of Firefox however certain features won't work and you will need to manually flip preferences to enable containers. All other sections of this guide talk about using the legacy setup with jpm.
|
||||
|
||||
|
||||
## Legacy Development
|
||||
|
||||
### Development Environment
|
||||
|
||||
Add-on development is better with [a particular environment](https://developer.mozilla.org/en-US/Add-ons/Setting_up_extension_development_environment). One simple way to get that environment set up is to install the [DevPrefs add-on](https://addons.mozilla.org/en-US/firefox/addon/devprefs/). You can make a custom Firefox profile that includes the DevPrefs add-on, and use that profile when you run the code in this repository.
|
||||
|
||||
1. Make a new profile by running `/path/to/firefox -P`, which launches the profile editor. "Create Profile" -- name it whatever you wish (e.g. 'addon_dev') and store it in the default location. It's probably best to deselect the option to "Use without asking," since you probably don't want to use this as your default profile.
|
||||
|
||||
2. Once you've created your profile, click "Start Firefox". A new instance of Firefox should launch. Go to Tools->Add-ons and search for "DevPrefs". Install it. Quit Firefox.
|
||||
|
||||
3. Now you have a new, vanilla Firefox profile with the DevPrefs add-on installed. You can use your new profile with the code in _this_ repository like so:
|
||||
|
||||
#### Run the `.xpi` file in an unbranded build
|
||||
Release & Beta channels do not allow un-signed add-ons, even with the DevPrefs. So, you must run the add-on in an [unbranded build](https://wiki.mozilla.org/Add-ons/Extension_Signing#Unbranded_Builds):
|
||||
|
||||
1. Download and install an un-branded build of Firefox
|
||||
2. Download the latest `.xpi` from this repository's releases
|
||||
3. Run the un-branded build of Firefox with your DevPrefs profile
|
||||
4. Go to `about:addons`
|
||||
5. Click the gear, and select "Install Add-on From File..."
|
||||
6. Select the `.xpi` file
|
||||
|
||||
#### Correct prefs
|
||||
|
||||
Whilst this is still using legacy code to test you will need the following in your profile:
|
||||
|
||||
Change the following prefs in about:config:
|
||||
|
||||
- extensions.legacy.enabled = true
|
||||
- xpinstall.signatures.required = false
|
||||
|
||||
|
||||
#### Run the TxP experiment with `jpm`
|
||||
|
||||
1. `git clone git@github.com:mozilla/testpilot-containers.git`
|
||||
2. `cd testpilot-containers`
|
||||
3. `npm install`
|
||||
4. `./node_modules/.bin/jpm run -p /Path/To/Firefox/Profiles/{junk}.addon_dev -b FirefoxBeta` (where FirefoxBeta might be: ~/<reponame>/obj-x86_64-pc-linux-gnu/dist/bin/firefox or ~/<downloadedFirefoxBeta>/firefox)
|
||||
|
||||
Check out the [Browser Toolbox](https://developer.mozilla.org/en-US/docs/Tools/Browser_Toolbox) for more information about debugging add-on code.
|
||||
|
||||
### Building .xpi
|
||||
|
||||
To build a local testpilot-containers.xpi, use the plain [`jpm
|
||||
xpi`](https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/jpm#jpm_xpi) command,
|
||||
or run `npm run build`.
|
||||
2. cd src; web-ext run -f Nightly
|
||||
|
||||
### Testing
|
||||
TBD
|
||||
|
@ -84,8 +27,7 @@ TBD
|
|||
### Distributing
|
||||
#### Make the new version
|
||||
|
||||
1. Bump the version number in `package.json`, `install.rdf`, and
|
||||
`manifest.json`
|
||||
1. Bump the version number in `package.json` and `manifest.json`
|
||||
2. Commit the version number bump
|
||||
3. Create a git tag for the version: `git tag <version>`
|
||||
4. Push the tag up to GitHub: `git push --tags`
|
||||
|
|
187
bootstrap.js
vendored
|
@ -1,187 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const PREFS = [
|
||||
{
|
||||
name: "privacy.userContext.enabled",
|
||||
value: true,
|
||||
type: "bool",
|
||||
default: false
|
||||
},
|
||||
{
|
||||
name: "privacy.userContext.longPressBehavior",
|
||||
value: 2,
|
||||
type: "int",
|
||||
default: 0
|
||||
},
|
||||
{
|
||||
name: "privacy.userContext.ui.enabled",
|
||||
value: true, // Post web ext we will be setting this true
|
||||
type: "bool",
|
||||
default: true
|
||||
},
|
||||
{
|
||||
name: "privacy.usercontext.about_newtab_segregation.enabled",
|
||||
value: true,
|
||||
type: "bool",
|
||||
default: false
|
||||
},
|
||||
];
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.importGlobalProperties(["TextEncoder", "TextDecoder"]);
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||
"resource://gre/modules/osfile.jsm");
|
||||
|
||||
const JETPACK_DIR_BASENAME = "jetpack";
|
||||
const EXTENSION_ID = "@testpilot-containers";
|
||||
|
||||
function loadStyles(resourceURI) {
|
||||
const styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"]
|
||||
.getService(Ci.nsIStyleSheetService);
|
||||
const styleURI = styleSheet(resourceURI);
|
||||
const sheetType = styleSheetService.AGENT_SHEET;
|
||||
styleSheetService.loadAndRegisterSheet(styleURI, sheetType);
|
||||
}
|
||||
|
||||
function styleSheet(resourceURI) {
|
||||
return Services.io.newURI("data/usercontext.css", null, resourceURI);
|
||||
}
|
||||
|
||||
function unloadStyles(resourceURI) {
|
||||
const styleURI = styleSheet(resourceURI);
|
||||
const styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"]
|
||||
.getService(Ci.nsIStyleSheetService);
|
||||
const sheetType = styleSheetService.AGENT_SHEET;
|
||||
if (styleSheetService.sheetRegistered(styleURI, sheetType)) {
|
||||
styleSheetService.unregisterSheet(styleURI, sheetType);
|
||||
}
|
||||
}
|
||||
|
||||
function filename() {
|
||||
const storeFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
|
||||
storeFile.append(JETPACK_DIR_BASENAME);
|
||||
storeFile.append(EXTENSION_ID);
|
||||
storeFile.append("simple-storage");
|
||||
storeFile.append("store.json");
|
||||
return storeFile.path;
|
||||
}
|
||||
|
||||
async function makeFilepath() {
|
||||
const storeFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
|
||||
storeFile.append(JETPACK_DIR_BASENAME);
|
||||
await OS.File.makeDir(storeFile.path, { ignoreExisting: true });
|
||||
storeFile.append(EXTENSION_ID);
|
||||
await OS.File.makeDir(storeFile.path, { ignoreExisting: true });
|
||||
storeFile.append("simple-storage");
|
||||
await OS.File.makeDir(storeFile.path, { ignoreExisting: true });
|
||||
}
|
||||
|
||||
async function getConfig() {
|
||||
let savedConfig = {savedConfiguration: {}};
|
||||
try {
|
||||
const bytes = await OS.File.read(filename());
|
||||
const raw = new TextDecoder().decode(bytes) || "";
|
||||
if (raw) {
|
||||
savedConfig = JSON.parse(raw);
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore file read errors, sometimes they happen and I'm not sure if we can fix
|
||||
}
|
||||
return savedConfig;
|
||||
}
|
||||
|
||||
async function initConfig() {
|
||||
const savedConfig = await getConfig();
|
||||
savedConfig.savedConfiguration.version = 2;
|
||||
if (!("prefs" in savedConfig.savedConfiguration)) {
|
||||
savedConfig.savedConfiguration.prefs = {};
|
||||
PREFS.forEach((pref) => {
|
||||
if ("int" === pref.type) {
|
||||
savedConfig.savedConfiguration.prefs[pref.name] = Services.prefs.getIntPref(pref.name);
|
||||
} else {
|
||||
savedConfig.savedConfiguration.prefs[pref.name] = Services.prefs.getBoolPref(pref.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
const serialized = JSON.stringify(savedConfig);
|
||||
const bytes = new TextEncoder().encode(serialized) || "";
|
||||
await makeFilepath();
|
||||
await OS.File.writeAtomic(filename(), bytes, { });
|
||||
}
|
||||
|
||||
function setPrefs() {
|
||||
PREFS.forEach((pref) => {
|
||||
if ("int" === pref.type) {
|
||||
Services.prefs.setIntPref(pref.name, pref.value);
|
||||
} else {
|
||||
Services.prefs.setBoolPref(pref.name, pref.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
async function install() {
|
||||
await initConfig();
|
||||
setPrefs();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
async function uninstall({resourceURI}, aReason) {
|
||||
if (checkLegacyFirefox()) {
|
||||
if (aReason === ADDON_UNINSTALL) {
|
||||
unloadStyles(resourceURI);
|
||||
await removeChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function removeChanges() {
|
||||
const config = await getConfig();
|
||||
const storedPrefs = config.savedConfiguration.prefs || {};
|
||||
PREFS.forEach((pref) => {
|
||||
let value = pref.default;
|
||||
if (pref.name in storedPrefs) {
|
||||
value = storedPrefs[pref.name];
|
||||
}
|
||||
if ("int" === pref.type) {
|
||||
Services.prefs.setIntPref(pref.name, value);
|
||||
} else {
|
||||
Services.prefs.setBoolPref(pref.name, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function checkLegacyFirefox() {
|
||||
const version = Services.appinfo.version;
|
||||
const versionMatch = version.match(/^([0-9]+)\./)[1];
|
||||
if (Number(versionMatch) <= 56) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function startup({webExtension, resourceURI}) {
|
||||
if (checkLegacyFirefox()) {
|
||||
loadStyles(resourceURI);
|
||||
// Reset prefs that may have changed, or are legacy
|
||||
install();
|
||||
}
|
||||
// Start the embedded webextension.
|
||||
webExtension.startup();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function shutdown({resourceURI}, aReason) {
|
||||
if (checkLegacyFirefox()) {
|
||||
unloadStyles(resourceURI);
|
||||
if (aReason === ADDON_DISABLE) {
|
||||
removeChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
23
install.rdf
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>@testpilot-containers</em:id>
|
||||
<em:type>2</em:type>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:multiprocessCompatible>true</em:multiprocessCompatible>
|
||||
<em:hasEmbeddedWebExtension>true</em:hasEmbeddedWebExtension>
|
||||
<em:name>Multi-Account Containers</em:name>
|
||||
<em:description>Containers helps you keep all the parts of your online life contained in different tabs. Custom labels and color-coded tabs help keep different activities — like online shopping, travel planning, or checking work email — separate.</em:description>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!--Firefox-->
|
||||
<em:minVersion>53.0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
<em:version>4.1.0</em:version>
|
||||
<em:unpack>false</em:unpack>
|
||||
</Description>
|
||||
</RDF>
|
||||
|
13
package.json
|
@ -2,7 +2,7 @@
|
|||
"name": "testpilot-containers",
|
||||
"title": "Multi-Account Containers",
|
||||
"description": "Containers helps you keep all the parts of your online life contained in different tabs. Custom labels and color-coded tabs help keep different activities — like online shopping, travel planning, or checking work email — separate.",
|
||||
"version": "4.1.0",
|
||||
"version": "5.0.0",
|
||||
"author": "Andrea Marchesini, Luke Crouch and Jonathan Kingston",
|
||||
"bugs": {
|
||||
"url": "https://github.com/mozilla/testpilot-containers/issues"
|
||||
|
@ -15,7 +15,6 @@
|
|||
"eslint-plugin-no-unsanitized": "^2.0.0",
|
||||
"eslint-plugin-promise": "^3.4.0",
|
||||
"htmllint-cli": "^0.0.5",
|
||||
"jpm": "^1.2.2",
|
||||
"json": "^9.0.6",
|
||||
"npm-run-all": "^4.0.0",
|
||||
"stylelint": "^7.9.0",
|
||||
|
@ -30,14 +29,14 @@
|
|||
"url": "git+https://github.com/mozilla/testpilot-containers.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm test && jpm xpi",
|
||||
"build": "npm test && cd src && web-ext build --overwrite-dest",
|
||||
"deploy": "deploy-txp",
|
||||
"lint": "npm-run-all lint:*",
|
||||
"lint:addon": "addons-linter webextension --self-hosted",
|
||||
"lint:css": "stylelint webextension/css/*.css",
|
||||
"lint:html": "htmllint webextension/*.html",
|
||||
"lint:addon": "addons-linter src --self-hosted",
|
||||
"lint:css": "stylelint src/css/*.css",
|
||||
"lint:html": "htmllint *.html",
|
||||
"lint:js": "eslint .",
|
||||
"package": "npm run build && mv testpilot-containers.xpi addon.xpi",
|
||||
"package": "rm -rf src/web-ext-artifacts && npm run build && mv src/web-ext-artifacts/firefox_multi-account_containers-*.zip addon.xpi",
|
||||
"test": "npm run lint"
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 307 B After Width: | Height: | Size: 307 B |
Before Width: | Height: | Size: 595 B After Width: | Height: | Size: 595 B |
Before Width: | Height: | Size: 520 B After Width: | Height: | Size: 520 B |
Before Width: | Height: | Size: 626 B After Width: | Height: | Size: 626 B |
Before Width: | Height: | Size: 603 B After Width: | Height: | Size: 603 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 883 B After Width: | Height: | Size: 883 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 342 B After Width: | Height: | Size: 342 B |
Before Width: | Height: | Size: 578 B After Width: | Height: | Size: 578 B |
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 307 B After Width: | Height: | Size: 307 B |
Before Width: | Height: | Size: 534 B After Width: | Height: | Size: 534 B |
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 755 B After Width: | Height: | Size: 755 B |
Before Width: | Height: | Size: 399 B After Width: | Height: | Size: 399 B |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Firefox Multi-Account Containers",
|
||||
"version": "4.1.0",
|
||||
"version": "5.0.0",
|
||||
|
||||
"description": "Multi-Account Containers helps you keep all the parts of your online life contained in different tabs. Custom labels and color-coded tabs help keep different activities — like online shopping, travel planning, or checking work email — separate.",
|
||||
"icons": {
|
||||
|
@ -11,7 +11,7 @@
|
|||
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"strict_min_version": "53.0"
|
||||
"strict_min_version": "57.0"
|
||||
}
|
||||
},
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
const main = require("../");
|
||||
|
||||
exports["test main"] = function(assert) {
|
||||
assert.pass("Unit test running!");
|
||||
};
|
||||
|
||||
exports["test main async"] = function(assert, done) {
|
||||
assert.pass("async Unit test running!");
|
||||
done();
|
||||
};
|
||||
|
||||
exports["test dummy"] = function(assert, done) {
|
||||
main.dummy("foo", function(text) {
|
||||
assert.ok((text === "foo"), "Is the text actually 'foo'");
|
||||
done();
|
||||
});
|
||||
};
|
||||
|
||||
require("sdk/test").run(exports);
|