Let selected settings be overridden per website, layered over the global config for the current page. Build the host-keyed plumbing once; each setting opts in.
Design
sites: BTreeMap<String, SiteOverride> on AppConfig (config/mod.rs:43), Option<T> per key — None falls back to global. #[serde(default)] is already everywhere, so old config files stay valid; sanitize() clamps with the existing bounds constants.
- Resolve in
request_navigation (browser/delegate.rs:61), not notify_url_changed — it fires before the load with webview + request.url, which is what makes the global-pref settings land in time. Check it also fires for embedder-driven load_url.
- Store resolved values per tab:
Tab (browser/mod.rs:90) + tab_index(webview.id()) already map WebViewId to per-tab state.
- Host key: extract the registrable-domain logic from
compute_brand_label (ui/home.rs:498-519) into a shared host_key(); don't write a second host parser.
Overridable settings
Ordered by fit. Per-load / per-webview settings are a natural match — do these first:
- Ad blocker on/off —
load_web_resource already gets _webview (unused); resolve via tab_index.
- Data saving —
ContentFilter is already a Copy snapshot (browser/content_filter.rs:17); move it from the global Cell into Tab.
- Page zoom — per-webview
set_page_zoom, already applied at build_tab; also apply on navigation.
- Record history — one host check at
app/mod.rs:129-143.
Global Servo prefs are awkward — "next load" semantics, do last:
- Experimental features —
servo.set_preference is process-global (servo-0.4.0/servo.rs:1082), no per-webview pref API in Servo 0.4. Applying in request_navigation should land before the new document; verify empirically (CSS Grid off for one host). Background tabs leak the foreground site's prefs on subframe loads — best-effort.
- User agent — currently
restart = true (settings/fields.rs:195), but net reads pref!(user_agent) live per request context (servo-net-0.4.0/resource_thread.rs:829,921), so runtime set_preference should work — verify. Also unlocks a live global UA toggle. Keywords already mapped by resolve_user_agent.
UI is the bulk of the work
FIELDS (settings/fields.rs:192) is a static table of fn(&AppConfig) pointers: hardwired to the global config, two-state rows. Per-site needs tri-state (Inherit / On / Off) over a dynamic subject, a "This site" section shown only when a host is known, and a list-with-delete so overrides aren't invisible cruft. Precedent: settings/controls.rs, the existing dynamic non-FIELDS section.
Notes
- Decide upfront: does manually zooming a site write into its override, or stay transient? Either way
zoom() / Zoom(0) reset (browser/mod.rs:649-674) must become site-aware.
Tab is built in four places (build_tab, open_tab, open_tab_background, delegate::request_create_new) — all need the new fields.
Let selected settings be overridden per website, layered over the global config for the current page. Build the host-keyed plumbing once; each setting opts in.
Design
sites: BTreeMap<String, SiteOverride>onAppConfig(config/mod.rs:43),Option<T>per key —Nonefalls back to global.#[serde(default)]is already everywhere, so old config files stay valid;sanitize()clamps with the existingboundsconstants.request_navigation(browser/delegate.rs:61), notnotify_url_changed— it fires before the load withwebview+request.url, which is what makes the global-pref settings land in time. Check it also fires for embedder-drivenload_url.Tab(browser/mod.rs:90) +tab_index(webview.id())already map WebViewId to per-tab state.compute_brand_label(ui/home.rs:498-519) into a sharedhost_key(); don't write a second host parser.Overridable settings
Ordered by fit. Per-load / per-webview settings are a natural match — do these first:
load_web_resourcealready gets_webview(unused); resolve viatab_index.ContentFilteris already aCopysnapshot (browser/content_filter.rs:17); move it from the globalCellintoTab.set_page_zoom, already applied atbuild_tab; also apply on navigation.app/mod.rs:129-143.Global Servo prefs are awkward — "next load" semantics, do last:
servo.set_preferenceis process-global (servo-0.4.0/servo.rs:1082), no per-webview pref API in Servo 0.4. Applying inrequest_navigationshould land before the new document; verify empirically (CSS Grid off for one host). Background tabs leak the foreground site's prefs on subframe loads — best-effort.restart = true(settings/fields.rs:195), but net readspref!(user_agent)live per request context (servo-net-0.4.0/resource_thread.rs:829,921), so runtimeset_preferenceshould work — verify. Also unlocks a live global UA toggle. Keywords already mapped byresolve_user_agent.UI is the bulk of the work
FIELDS(settings/fields.rs:192) is a static table offn(&AppConfig)pointers: hardwired to the global config, two-state rows. Per-site needs tri-state (Inherit / On / Off) over a dynamic subject, a "This site" section shown only when a host is known, and a list-with-delete so overrides aren't invisible cruft. Precedent:settings/controls.rs, the existing dynamic non-FIELDSsection.Notes
zoom()/Zoom(0)reset (browser/mod.rs:649-674) must become site-aware.Tabis built in four places (build_tab,open_tab,open_tab_background,delegate::request_create_new) — all need the new fields.