tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

0002-browser-search-rewrite.md (9215B)



layout: page title: Replacing browser-search component with state in browser-store permalink: /rfc/0002-search-state-in-browser-store


Summary

Moving all search related state to BrowserState and replacing SearchEngineManager with a BrowserStore middleware that deals with saving and loading state; better satisfying the requirements of Fenix and Focus.

Motivation

The integration of browser-search into Fenix and Firefox for Fire TV showed that the current API is not enough to satisfy all use cases. Some examples include:

Guide-level explanation

Instead of making SearchEngine instances accessible through SearchEngineManager via a browser-search component, we want to make SearchEngine(State) available in BrowserState. A middleware on the BrowserStore will transparently take care of loading SearchEngine instances. Whenever the app dispatches an action to change the list of search engines (e.g. adding a custom search engine) then the middleware will take care of saving the new state to disk.

This will allow the app to use the already proven pattern of observing a store to update UI and makes it easy to mix search state with other state without having to query multiple sources. In addition to that the app no longer needs to take care of the storage and fallbacks (e.g. slow MLS query) since that can be handled completely by the middleware.

Using the BrowserStore for state will make the app use asynchronous patterns to observe the state and with that avoid blocking the main thread, as well as force the app to deal with the initial state of having no (default) SearchEngine yet.

Since the state will move to browser-state, additional functionality (querying suggestions, storage, middleware) can move to feature-search. This will make browser-search obsolete. With that introducing a concept-search is not required. An app can use a custom implementation by replacing the middleware, storage or handling search state completely differently.

Reference-level explanation

The new implementation will use browser-state to model all search state.

Functionality on top of the state (querying suggestions, storage, middleware) will live in feature-search. With that browser-search will no longer be needed and can be removed after following the deprecation process.

State

BrowserState will get a new search property with SearchState type that lives in browser-state:

data class BrowserState(
   // ...
   val search: SearchState
)

/**
 * Value type that represents the state of available search engines.
 *
 * @property searchEngines List of loaded search engines.
 * @property defaultSearchEngineId ID of the default search engine.
 */
data class SearchState(
  val searchEngines: List<SearchEngine>,
  val defaultSearchEngineId: String
)

SearchState will contain all SearchEngines (bundled and custom). Additional extension methods will make it easier to select specific subsets or the default SearchEngine.

SearchEngine will be turned into a data class and moved to browser-store. A type property will make custom and provided default search engines distinguishable. Other methods like buildSearchUrl() will be implemented as extension methods.

Storage

There will be two storage classes:

Those storage classes will have visibility internal and will not be used by the app directly.

All storage access methods will be suspending functions to avoid thread-blocking access:

internal class SearchEngineStorage {
    suspend fun getSearchEngines() = withContext(Dispatchers.IO) {
      // ...
    }
}

Middleware

A SearchMiddleware that will be installed on BrowserStore will be responsible for:

* Adding search engines * Removing search engines * Changing the default search engine

Fallback behavior (e.g. region cannot be determined) will be handled by the middleware.

Drawbacks

Rationale and alternatives

Prior art

We have implemented similar functionality a lot of times:

Unresolved questions

* Firefox Preview (Fenix) * Firefox Focus/Klar * Firefox Reality * Firefox for Fire TV * Firefox for Echo Show