Expand description
§ffcv - Firefox Configuration Viewer Library
This library provides functionality for parsing and querying Firefox preference files (prefs.js). It can parse Firefox’s custom JavaScript-like preference format, manage Firefox profiles, and filter preferences by glob patterns.
§Features
- Parse Firefox prefs.js files with full JavaScript escape sequence support
- Extract and merge Firefox’s built-in default preferences from omni.ja archives
- Auto-discover Firefox installations across platforms (Linux, macOS, Windows)
- Detect and manage Firefox profiles across platforms
- Query preferences using glob patterns (e.g.,
"network.*","browser.*.enabled") - Get human-readable explanations for documented preferences
- Support for all four preference types: user, default, locked, and sticky
- Track preference sources (built-in, global defaults, user-modified)
§Quick Start
§Parsing Preferences
use ffcv::{parse_prefs_js, PrefType, PrefValue};
let content = r#"
user_pref("browser.startup.homepage", "https://example.com");
pref("javascript.enabled", true);
lock_pref("security.default_ssl_enabled", false);
"#;
let prefs = parse_prefs_js(content)?;
let homepage = prefs.iter()
.find(|e| e.key == "browser.startup.homepage")
.unwrap();
assert_eq!(homepage.value, PrefValue::String("https://example.com".to_string()));
assert_eq!(homepage.pref_type, PrefType::User);For convenient value type checking, import the PrefValueExt trait:
use ffcv::{parse_prefs_js, PrefValue, PrefValueExt};
let content = r#"user_pref("javascript.enabled", true);"#;
let prefs = parse_prefs_js(content)?;
let entry = &prefs[0];
// Use convenience methods from PrefValueExt
if let Some(enabled) = entry.value.as_bool() {
println!("JavaScript enabled: {}", enabled);
}§Working with Profiles
use ffcv::{find_profile_path, parse_prefs_js};
// Find a specific Firefox profile
let profile_path = find_profile_path("default", None)?;
let prefs_path = profile_path.join("prefs.js");
// Read and parse preferences
let content = std::fs::read_to_string(&prefs_path)?;
let prefs = parse_prefs_js(&content)?;§Listing All Profiles
use ffcv::list_profiles;
let profiles = list_profiles(None)?;
for profile in profiles {
println!("Profile: {} ({})", profile.name, profile.path.display());
if profile.is_default {
println!(" (default profile)");
}
}§Querying Preferences
use ffcv::{parse_prefs_js, query_preferences};
let content = r#"
user_pref("network.proxy.http", "proxy.example.com");
user_pref("network.proxy.http_port", 8080);
user_pref("browser.startup.homepage", "https://example.com");
"#;
let prefs = parse_prefs_js(content)?;
let network_prefs = query_preferences(&prefs, &["network.*"])?;
assert_eq!(network_prefs.len(), 2);
assert!(network_prefs.iter().any(|e| e.key == "network.proxy.http"));§Firefox Installation Discovery
use ffcv::find_firefox_installation;
// Auto-detect Firefox installation on your system
match find_firefox_installation()? {
Some(installation) => {
println!("Firefox found at: {}", installation.path.display());
println!("Version: {}", installation.version);
println!("Has omni.ja: {}", installation.has_omni_ja);
}
None => println!("No Firefox installation found"),
}§Merging All Preference Sources
use ffcv::{merge_all_preferences, find_profile_path, MergeConfig};
let profile_path = find_profile_path("default-release", None)?;
let config = MergeConfig {
include_builtins: true, // Include omni.ja defaults
include_globals: true, // Include greprefs.js
include_user: true, // Include user prefs.js
continue_on_error: true, // Don't fail if some sources are missing
};
let merged = merge_all_preferences(&profile_path, None, &config)?;
println!("Loaded {} preferences from {} sources",
merged.entries.len(),
merged.loaded_sources.len()
);
// Display warnings for any missing sources
for warning in &merged.warnings {
eprintln!("Warning: {}", warning);
}§Filtering User-Modified Preferences
use ffcv::{merge_all_preferences, find_profile_path, MergeConfig, PrefSource};
let profile_path = find_profile_path("default-release", None)?;
let config = MergeConfig::default();
let merged = merge_all_preferences(&profile_path, None, &config)?;
// Get only user-modified preferences (exclude built-ins)
let user_modified: Vec<_> = merged.entries
.iter()
.filter(|p| p.source == Some(PrefSource::User))
.collect();
println!("You've modified {} preferences", user_modified.len());§Preference Types
Firefox supports four preference types, indicated by the function name used:
- user_pref() -
PrefType::User: User-set preferences (most common) - pref() -
PrefType::Default: Application defaults - lock_pref() -
PrefType::Locked: Locked preferences (cannot be changed by users) - sticky_pref() -
PrefType::Sticky: Sticky preferences (persist across updates)
§Error Handling
All functions return Result<T, Error>. The Error enum provides
detailed error context for programmatic handling:
use ffcv::{parse_prefs_js, Error};
let invalid_content = "user_pref(invalid syntax";
match parse_prefs_js(invalid_content) {
Ok(config) => println!("Parsed successfully"),
Err(Error::Parser { line, column, message }) => {
eprintln!("Parse error at {}:{}: {}", line, column, message);
}
Err(e) => eprintln!("Other error: {}", e),
}§Platform Support
This library automatically detects Firefox profiles on:
- Linux:
~/.mozilla/firefox/ - macOS:
~/Library/Application Support/Firefox/ - Windows:
%APPDATA%\Mozilla\Firefox\Profiles\
§See Also
Structs§
- Extract
Config - Configuration for omni.ja extraction
- Firefox
Installation - Firefox installation information
- Merge
Config - Configuration for preference merging
- Merged
Preferences - Merged preferences from multiple sources
- Omni
Extractor - omni.ja archive extractor
- Pref
Entry - Internal type for parser that always includes pref type
- Profile
Info - Public profile information for listing
Enums§
- Error
- Errors that can occur during Firefox preference parsing and operations
- Pref
Source - Firefox preference source
- Pref
Type - Firefox preference types
- Pref
Value - Firefox preference value types
Constants§
- DEFAULT_
MAX_ OMNI_ SIZE - Default maximum omni.ja file size (100MB)
Traits§
- Pref
Value Ext - Extension trait providing convenience methods for PrefValue
Functions§
- find_
all_ firefox_ installations - Find all Firefox installations on the system
- find_
firefox_ installation - Find the first valid Firefox installation on the system
- find_
profile_ path - Find the Firefox profile directory based on the profile name
- get_
effective_ pref - Get the effective value for a preference key
- get_
firefox_ version - Get the Firefox version from an installation directory
- get_
prefs_ path - Get the path to prefs.js for a given profile
- list_
profiles - List all available Firefox profiles
- merge_
all_ preferences - Merge preferences from multiple sources
- parse_
prefs_ js - Parse the prefs.js file and extract all preferences
- parse_
prefs_ js_ file - Parse a prefs.js file directly from a file path
- query_
preferences - Query configuration preferences by glob patterns (OR logic)
Type Aliases§
- Result
- Result type alias for convenience