{ config, lib, pkgs, ... }: with lib; let inherit (pkgs.stdenv.hostPlatform) isDarwin; cfg = config.programs.firefox; jsonFormat = pkgs.formats.json { }; mozillaConfigPath = if isDarwin then "Library/Application Support/Mozilla" else ".mozilla"; firefoxConfigPath = if isDarwin then "Library/Application Support/Firefox" else "${mozillaConfigPath}/firefox"; profilesPath = if isDarwin then "${firefoxConfigPath}/Profiles" else firefoxConfigPath; nativeMessagingHostsPath = if isDarwin then "${mozillaConfigPath}/NativeMessagingHosts" else "${mozillaConfigPath}/native-messaging-hosts"; nativeMessagingHostsJoined = pkgs.symlinkJoin { name = "ff_native-messaging-hosts"; paths = [ # Link a .keep file to keep the directory around (pkgs.writeTextDir "lib/mozilla/native-messaging-hosts/.keep" "") # Link package configured native messaging hosts (entire Firefox actually) cfg.finalPackage ] # Link user configured native messaging hosts ++ cfg.nativeMessagingHosts; }; # The extensions path shared by all profiles; will not be supported # by future Firefox versions. extensionPath = "extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"; profiles = flip mapAttrs' cfg.profiles (_: profile: nameValuePair "Profile${toString profile.id}" { Name = profile.name; Path = if isDarwin then "Profiles/${profile.path}" else profile.path; IsRelative = 1; Default = if profile.isDefault then 1 else 0; }) // { General = { StartWithLastProfile = 1; }; }; profilesIni = generators.toINI { } profiles; userPrefValue = pref: builtins.toJSON (if isBool pref || isInt pref || isString pref then pref else builtins.toJSON pref); mkUserJs = prefs: extraPrefs: bookmarks: let prefs' = lib.optionalAttrs ([ ] != bookmarks) { "browser.bookmarks.file" = toString (firefoxBookmarksFile bookmarks); "browser.places.importBookmarksHTML" = true; } // prefs; in '' // Generated by Home Manager. ${concatStrings (mapAttrsToList (name: value: '' user_pref("${name}", ${userPrefValue value}); '') prefs')} ${extraPrefs} ''; mkContainersJson = containers: let containerToIdentity = _: container: { userContextId = container.id; name = container.name; icon = container.icon; color = container.color; public = true; }; in '' ${builtins.toJSON { version = 4; lastUserContextId = foldlAttrs (acc: _: value: if value.id > acc then value.id else acc) 0 containers; identities = mapAttrsToList containerToIdentity containers ++ [ { userContextId = 4294967294; # 2^32 - 2 name = "userContextIdInternal.thumbnail"; icon = ""; color = ""; accessKey = ""; public = false; } { userContextId = 4294967295; # 2^32 - 1 name = "userContextIdInternal.webextStorageLocal"; icon = ""; color = ""; accessKey = ""; public = false; } ]; }} ''; firefoxBookmarksFile = bookmarks: let indent = level: lib.concatStringsSep "" (map (lib.const " ") (lib.range 1 level)); bookmarkToHTML = indentLevel: bookmark: '' ${indent indentLevel}
${allItemsToHTML (indentLevel + 1) directory.bookmarks} ${indent indentLevel}
''; itemToHTMLOrRecurse = indentLevel: item: if item ? "url" then bookmarkToHTML indentLevel item else directoryToHTML indentLevel item; allItemsToHTML = indentLevel: bookmarks: lib.concatStringsSep "\n" (map (itemToHTMLOrRecurse indentLevel) bookmarks); bookmarkEntries = allItemsToHTML 1 bookmarks; in pkgs.writeText "firefox-bookmarks.html" ''
${bookmarkEntries}