Added a module to configure browser based on the gecko engine, such as Firefox.
This module should provide similar functionality to the firefox module in home-manager. Some notable differences between the two include: * home-manager configures a single browser. This means that any configuration that cannot be done on a per-profile basis is shared between all profiles. This module configures a new copy of the browser for every profile, ensuring that *all* configuration can be on a per-profile basis. This might be seen as insanity in a regular distro, but in NixOS this is trivial to do and requires no extra storage space. * home-manager modifies files in the user's directory to configure things such as extensions and search engines. This module avoids that when possible by pushing configuration into policies and preferences at a browser level. This is much nicer for impermanence-based systems.
This commit is contained in:
parent
977595f7e8
commit
0f0c4c7727
10 changed files with 962 additions and 1 deletions
157
modules/home-manager/gecko-browser/gecko-lib/extensions.nix
Normal file
157
modules/home-manager/gecko-browser/gecko-lib/extensions.nix
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
info,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
submodule =
|
||||
{ name, ... }:
|
||||
{
|
||||
options = {
|
||||
packages = lib.mkOption {
|
||||
type =
|
||||
lib.types.listOf
|
||||
<| lib.types.either lib.types.package
|
||||
<| lib.types.submodule {
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
example = "ublock-origin";
|
||||
description = "The short name of the extension. To find the short name look at the extension's download link.";
|
||||
};
|
||||
|
||||
guid = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "uBlock0@raymondhill.net";
|
||||
description = "The guid of the extension. To find the guid go to https://addons.mozilla.org/api/v5/addons/addon/\${shortName}/";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = [ ];
|
||||
description = ''
|
||||
Extensions to install for this profile. Takes either a package or a description of an extension.
|
||||
* If a package is given, the extension will be preinstalled.
|
||||
* If a description is given then ${info.name} will download the extension on startup.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
type =
|
||||
let
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
in
|
||||
lib.types.attrsOf jsonFormat.type;
|
||||
default = { };
|
||||
description = "Settings for this extension, accessible by the managed storage API. The extension must be referenced by id.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# (Package -> a) -> ({ name, guid } -> a) -> Extension -> a
|
||||
withExtension =
|
||||
f: g: x:
|
||||
if lib.isDerivation x then f x else g x;
|
||||
|
||||
# ublock-origin wants its settings as a string, which is annoying
|
||||
# to merge. For convenience, you can keep ublock-origin's config
|
||||
# as a set and this function will turn it into a string at the
|
||||
# last minute. As a bonus, we can also do other magic for other
|
||||
# extensions if need be.
|
||||
magicInfo = {
|
||||
"uBlock0@raymondhill.net" =
|
||||
x:
|
||||
x
|
||||
// lib.optionalAttrs (x ? adminSettings) {
|
||||
adminSettings =
|
||||
builtins.toJSON
|
||||
<| (
|
||||
y:
|
||||
y
|
||||
// lib.optionalAttrs (y ? userFilters) {
|
||||
userFilters = builtins.concatStringsSep "\n" y.userFilters;
|
||||
}
|
||||
)
|
||||
<| (
|
||||
y:
|
||||
y
|
||||
// lib.optionalAttrs (y ? urlFilteringString) {
|
||||
urlFilteringString = builtins.concatStringsSep "\n" y.urlFilteringString;
|
||||
}
|
||||
)
|
||||
<| (
|
||||
y:
|
||||
y
|
||||
// lib.optionalAttrs (y ? hostnameSwitchesString) {
|
||||
hostnameSwitchesString = builtins.concatStringsSep "\n" y.hostnameSwitchesString;
|
||||
}
|
||||
)
|
||||
<| (
|
||||
y:
|
||||
y
|
||||
// lib.optionalAttrs (y ? dynamicFilteringString) {
|
||||
dynamicFilteringString = builtins.concatStringsSep "\n" y.dynamicFilteringString;
|
||||
}
|
||||
)
|
||||
<| x.adminSettings;
|
||||
};
|
||||
};
|
||||
magic = guid: magicInfo.${guid} or lib.trivial.id;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
extensions = lib.mkOption {
|
||||
type = lib.types.submodule submodule;
|
||||
default = { };
|
||||
# example = {
|
||||
# packages = [
|
||||
# nur.repos.rycee.firefox-addons.ublock-origin
|
||||
# { name = "decentraleyes"; guid = "jid1-BoFifL9Vbdl2zQ@jetpack"; }
|
||||
# ];
|
||||
# settings."uBlock0@raymondhill.net" = {
|
||||
# whitelist = [ "example.org" ];
|
||||
# };
|
||||
# };
|
||||
description = "The extensions to install.";
|
||||
};
|
||||
};
|
||||
|
||||
process =
|
||||
{ extensions, ... }:
|
||||
{
|
||||
policies = {
|
||||
"3rdparty".Extensions = extensions.settings;
|
||||
ExtensionSettings =
|
||||
builtins.listToAttrs
|
||||
<| builtins.map (
|
||||
withExtension
|
||||
(x: {
|
||||
name = x.addonId;
|
||||
value = {
|
||||
installation_mode = "force_installed";
|
||||
private_browsing = true;
|
||||
install_url = "file://${x}/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}/${x.addonId}.xpi";
|
||||
};
|
||||
})
|
||||
(x: {
|
||||
name = x.guid;
|
||||
value = {
|
||||
installation_mode = "force_installed";
|
||||
private_browsing = true;
|
||||
install_url = "https://addons.mozilla.org/firefox/downloads/latest/${x.name}/latest.xpi";
|
||||
};
|
||||
})
|
||||
)
|
||||
<| extensions.packages;
|
||||
};
|
||||
prefs."extensions.autoDisableScopes" = 0;
|
||||
};
|
||||
|
||||
postprocess =
|
||||
{ policies, ... }:
|
||||
lib.optionalAttrs (policies ? "3rdparty".Extensions) {
|
||||
policies."3rdparty".Extensions = builtins.mapAttrs magic <| policies."3rdparty".Extensions or { };
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue