{ modulePath , name , description ? null , wrappedPackageName ? null , wrappedPkg ? null , unwrappedPackageName ? null , platforms , visible ? false , }: { config , lib , pkgs , ... }: with lib; let inherit (pkgs.stdenv.hostPlatform) isDarwin; moduleName = concatStringsSep "." modulePath; cfg = getAttrFromPath modulePath config; jsonFormat = pkgs.formats.json { }; supportedPlatforms = flatten (attrVals (attrNames platforms) lib.platforms); isWrapped = versionAtLeast config.home.stateVersion "19.09" && wrappedPackageName != null; defaultPackageName = if isWrapped then wrappedPackageName else unwrappedPackageName; packageName = if wrappedPackageName != null then wrappedPackageName else unwrappedPackageName; profilesPath = if isDarwin then "${cfg.configPath}/Profiles" else cfg.configPath; nativeMessagingHostsPath = if isDarwin then "${cfg.vendorPath}/NativeMessagingHosts" else "${cfg.vendorPath}/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 browser actually) cfg.finalPackage ] # Link user configured native messaging hosts ++ cfg.nativeMessagingHosts; }; # The extensions path shared by all profiles; will not be supported # by future browser 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; ZenAvatarPath = "chrome://browser/content/zen-avatars/avatar-91.svg"; } ) // { General = { StartWithLastProfile = 1; Version = 2; }; }; 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 (browserBookmarksFile 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 = elemAt (mapAttrsToList (_: container: container.id) containers) 0; 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; } ]; }} ''; browserBookmarksFile = 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 "${packageName}-bookmarks.html" ''
${bookmarkEntries}