summaryrefslogtreecommitdiffstats
path: root/browser/components/urlbar/docs/overview.rst
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:44:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:44:51 +0000
commit9e3c08db40b8916968b9f30096c7be3f00ce9647 (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /browser/components/urlbar/docs/overview.rst
parentInitial commit. (diff)
downloadthunderbird-upstream.tar.xz
thunderbird-upstream.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/components/urlbar/docs/overview.rst')
-rw-r--r--browser/components/urlbar/docs/overview.rst413
1 files changed, 413 insertions, 0 deletions
diff --git a/browser/components/urlbar/docs/overview.rst b/browser/components/urlbar/docs/overview.rst
new file mode 100644
index 0000000000..0ff1ee5ad7
--- /dev/null
+++ b/browser/components/urlbar/docs/overview.rst
@@ -0,0 +1,413 @@
+Architecture Overview
+=====================
+
+The address bar is implemented as a *model-view-controller* (MVC) system. One of
+the scopes of this architecture is to allow easy replacement of its components,
+for easier experimentation.
+
+Each search is represented by a unique object, the *UrlbarQueryContext*. This
+object, created by the *View*, describes the search and is passed through all of
+the components, along the way it gets augmented with additional information.
+The *UrlbarQueryContext* is passed to the *Controller*, and finally to the
+*Model*. The model appends results to a property of *UrlbarQueryContext* in
+chunks, it sorts them through a *Muxer* and then notifies the *Controller*.
+
+See the specific components below, for additional details about each one's tasks
+and responsibilities.
+
+
+The UrlbarQueryContext
+----------------------
+
+The *UrlbarQueryContext* object describes a single instance of a search.
+It is augmented as it progresses through the system, with various information:
+
+.. highlight:: JavaScript
+.. code::
+
+ UrlbarQueryContext {
+ allowAutofill; // {boolean} If true, providers are allowed to return
+ // autofill results. Even if true, it's up to providers
+ // whether to include autofill results, but when false, no
+ // provider should include them.
+ isPrivate; // {boolean} Whether the search started in a private context.
+ maxResults; // {integer} The maximum number of results requested. It is
+ // possible to request more results than the shown ones, and
+ // do additional filtering at the View level.
+ searchString; // {string} The user typed string.
+ userContextId; // {integer} The user context ID (containers feature).
+
+ // Optional properties.
+ muxer; // {string} Name of a registered muxer. Muxers can be registered
+ // through the UrlbarProvidersManager.
+ providers; // {array} List of registered provider names. Providers can be
+ // registered through the UrlbarProvidersManager.
+ sources: {array} list of accepted UrlbarUtils.RESULT_SOURCE for the context.
+ // This allows to switch between different search modes. If not
+ // provided, a default will be generated by the Model, depending on
+ // the search string.
+ engineName: // {string} if sources is restricting to just SEARCH, this
+ // property can be used to pick a specific search engine, by
+ // setting it to the name under which the engine is registered
+ // with the search service.
+ currentPage: // {string} url of the page that was loaded when the search
+ // began.
+ prohibitRemoteResults:
+ // {boolean} This provides a short-circuit override for
+ // context.allowRemoteResults(). If it's false, then allowRemoteResults()
+ // will do its usual checks to determine whether remote results are
+ // allowed. If it's true, then allowRemoteResults() will immediately
+ // return false. Defaults to false.
+
+ // Properties added by the Model.
+ results; // {array} list of UrlbarResult objects.
+ tokens; // {array} tokens extracted from the searchString, each token is an
+ // object in the form {type, value, lowerCaseValue}.
+ }
+
+
+The Model
+---------
+
+The *Model* is the component responsible for retrieving search results based on
+the user's input, and sorting them accordingly to their importance.
+At the core is the `UrlbarProvidersManager <https://searchfox.org/mozilla-central/source/browser/components/urlbar/UrlbarProvidersManager.jsm>`_,
+a component tracking all the available search providers, and managing searches
+across them.
+
+The *UrlbarProvidersManager* is a singleton, it registers internal providers on
+startup and can register/unregister providers on the fly.
+It can manage multiple concurrent queries, and tracks them internally as
+separate *Query* objects.
+
+The *Controller* starts and stops queries through the *UrlbarProvidersManager*.
+It's possible to wait for the promise returned by *startQuery* to know when no
+more results will be returned, it is not mandatory though.
+Queries can be canceled.
+
+.. note::
+
+ Canceling a query will issue an interrupt() on the database connection,
+ terminating any running and future SQL query, unless a query is running inside
+ a *runInCriticalSection* task.
+
+The *searchString* gets tokenized by the `UrlbarTokenizer <https://searchfox.org/mozilla-central/source/browser/components/urlbar/UrlbarTokenizer.jsm>`_
+component into tokens, some of these tokens have a special meaning and can be
+used by the user to restrict the search to specific result type (See the
+*UrlbarTokenizer::TYPE* enum).
+
+.. caution::
+
+ The tokenizer uses heuristics to determine each token's type, as such the
+ consumer may want to check the value before applying filters.
+
+.. highlight:: JavaScript
+.. code::
+
+ UrlbarProvidersManager {
+ registerProvider(providerObj);
+ unregisterProvider(providerObj);
+ registerMuxer(muxerObj);
+ unregisterMuxer(muxerObjOrName);
+ async startQuery(queryContext);
+ cancelQuery(queryContext);
+ // Can be used by providers to run uninterruptible queries.
+ runInCriticalSection(taskFn);
+ }
+
+UrlbarProvider
+~~~~~~~~~~~~~~
+
+A provider is specialized into searching and returning results from different
+information sources. Internal providers are usually implemented in separate
+*jsm* modules with a *UrlbarProvider* name prefix. External providers can be
+registered as *Objects* through the *UrlbarProvidersManager*.
+Each provider is independent and must satisfy a base API, while internal
+implementation details may vary deeply among different providers.
+
+.. important::
+
+ Providers are singleton, and must track concurrent searches internally, for
+ example mapping them by UrlbarQueryContext.
+
+.. note::
+
+ Internal providers can access the Places database through the
+ *PlacesUtils.promiseLargeCacheDBConnection* utility.
+
+.. highlight:: JavaScript
+.. code::
+
+ class UrlbarProvider {
+ /**
+ * Unique name for the provider, used by the context to filter on providers.
+ * Not using a unique name will cause the newest registration to win.
+ * @abstract
+ */
+ get name() {
+ return "UrlbarProviderBase";
+ }
+ /**
+ * The type of the provider, must be one of UrlbarUtils.PROVIDER_TYPE.
+ * @abstract
+ */
+ get type() {
+ throw new Error("Trying to access the base class, must be overridden");
+ }
+ /**
+ * Whether this provider should be invoked for the given context.
+ * If this method returns false, the providers manager won't start a query
+ * with this provider, to save on resources.
+ * @param {UrlbarQueryContext} queryContext The query context object
+ * @returns {boolean} Whether this provider should be invoked for the search.
+ * @abstract
+ */
+ isActive(queryContext) {
+ throw new Error("Trying to access the base class, must be overridden");
+ }
+ /**
+ * Gets the provider's priority. Priorities are numeric values starting at
+ * zero and increasing in value. Smaller values are lower priorities, and
+ * larger values are higher priorities. For a given query, `startQuery` is
+ * called on only the active and highest-priority providers.
+ * @param {UrlbarQueryContext} queryContext The query context object
+ * @returns {number} The provider's priority for the given query.
+ * @abstract
+ */
+ getPriority(queryContext) {
+ // By default, all providers share the lowest priority.
+ return 0;
+ }
+ /**
+ * Starts querying.
+ * @param {UrlbarQueryContext} queryContext The query context object
+ * @param {function} addCallback Callback invoked by the provider to add a new
+ * result. A UrlbarResult should be passed to it.
+ * @note Extended classes should return a Promise resolved when the provider
+ * is done searching AND returning results.
+ * @abstract
+ */
+ startQuery(queryContext, addCallback) {
+ throw new Error("Trying to access the base class, must be overridden");
+ }
+ /**
+ * Cancels a running query,
+ * @param {UrlbarQueryContext} queryContext The query context object to cancel
+ * query for.
+ * @abstract
+ */
+ cancelQuery(queryContext) {
+ throw new Error("Trying to access the base class, must be overridden");
+ }
+ }
+
+UrlbarMuxer
+~~~~~~~~~~~
+
+The *Muxer* is responsible for sorting results based on their importance and
+additional rules that depend on the UrlbarQueryContext. The muxer to use is
+indicated by the UrlbarQueryContext.muxer property.
+
+.. caution::
+
+ The Muxer is a replaceable component, as such what is described here is a
+ reference for the default View, but may not be valid for other implementations.
+
+.. highlight:: JavaScript
+.. code::
+
+ class UrlbarMuxer {
+ /**
+ * Unique name for the muxer, used by the context to sort results.
+ * Not using a unique name will cause the newest registration to win.
+ * @abstract
+ */
+ get name() {
+ return "UrlbarMuxerBase";
+ }
+ /**
+ * Sorts UrlbarQueryContext results in-place.
+ * @param {UrlbarQueryContext} queryContext the context to sort results for.
+ * @abstract
+ */
+ sort(queryContext) {
+ throw new Error("Trying to access the base class, must be overridden");
+ }
+ }
+
+
+The Controller
+--------------
+
+`UrlbarController <https://searchfox.org/mozilla-central/source/browser/components/urlbar/UrlbarController.jsm>`_
+is the component responsible for reacting to user's input, by communicating
+proper course of action to the Model (e.g. starting/stopping a query) and the
+View (e.g. showing/hiding a panel). It is also responsible for reporting Telemetry.
+
+.. note::
+
+ Each *View* has a different *Controller* instance.
+
+.. highlight:: JavaScript
+.. code::
+
+ UrlbarController {
+ async startQuery(queryContext);
+ cancelQuery(queryContext);
+ // Invoked by the ProvidersManager when results are available.
+ receiveResults(queryContext);
+ // Used by the View to listen for results.
+ addQueryListener(listener);
+ removeQueryListener(listener);
+ }
+
+
+The View
+--------
+
+The View is the component responsible for presenting search results to the
+user and handling their input.
+
+.. caution
+
+ The View is a replaceable component, as such what is described here is a
+ reference for the default View, but may not be valid for other implementations.
+
+`UrlbarInput.jsm <https://searchfox.org/mozilla-central/source/browser/components/urlbar/UrlbarInput.jsm>`_
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Implements an input box *View*, owns an *UrlbarView*.
+
+.. highlight:: JavaScript
+.. code::
+
+ UrlbarInput {
+ constructor(options = { textbox, panel });
+ // Uses UrlbarValueFormatter to highlight the base host, search aliases
+ // and to keep the host visible on overflow.
+ formatValue(val);
+ openResults();
+ // Converts an internal URI (e.g. a URI with a username or password) into
+ // one which we can expose to the user.
+ makeURIReadable(uri);
+ // Handles an event which would cause a url or text to be opened.
+ handleCommand();
+ // Called by the view when a result is selected.
+ resultsSelected();
+ // The underlying textbox
+ textbox;
+ // The results panel.
+ panel;
+ // The containing window.
+ window;
+ // The containing document.
+ document;
+ // An UrlbarController instance.
+ controller;
+ // An UrlbarView instance.
+ view;
+ // Whether the current value was typed by the user.
+ valueIsTyped;
+ // Whether the context is in Private Browsing mode.
+ isPrivate;
+ // Whether the input box is focused.
+ focused;
+ // The go button element.
+ goButton;
+ // The current value, can also be set.
+ value;
+ }
+
+`UrlbarView.jsm <https://searchfox.org/mozilla-central/source/browser/components/urlbar/UrlbarView.jsm>`_
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Represents the base *View* implementation, communicates with the *Controller*.
+
+.. highlight:: JavaScript
+.. code::
+
+ UrlbarView {
+ // Manage View visibility.
+ open();
+ close();
+ // Invoked when the query starts.
+ onQueryStarted(queryContext);
+ // Invoked when new results are available.
+ onQueryResults(queryContext);
+ // Invoked when the query has been canceled.
+ onQueryCancelled(queryContext);
+ // Invoked when the query is done. This is invoked in any case, even if the
+ // query was canceled earlier.
+ onQueryFinished(queryContext);
+ // Invoked when the view opens.
+ onViewOpen();
+ // Invoked when the view closes.
+ onViewClose();
+ }
+
+
+UrlbarResult
+------------
+
+An `UrlbarResult <https://searchfox.org/mozilla-central/source/browser/components/urlbar/UrlbarResult.jsm>`_
+instance represents a single search result with a result type, that
+identifies specific kind of results.
+Each kind has its own properties, that the *View* may support, and a few common
+properties, supported by all of the results.
+
+.. note::
+
+ Result types are also enumerated by *UrlbarUtils.RESULT_TYPE*.
+
+.. code-block::
+
+ UrlbarResult {
+ constructor(resultType, payload);
+
+ type: {integer} One of UrlbarUtils.RESULT_TYPE.
+ source: {integer} One of UrlbarUtils.RESULT_SOURCE.
+ title: {string} A title that may be used as a label for this result.
+ icon: {string} Url of an icon for this result.
+ payload: {object} Object containing properties for the specific RESULT_TYPE.
+ autofill: {object} An object describing the text that should be
+ autofilled in the input when the result is selected, if any.
+ autofill.value: {string} The autofill value.
+ autofill.selectionStart: {integer} The first index in the autofill
+ selection.
+ autofill.selectionEnd: {integer} The last index in the autofill selection.
+ suggestedIndex: {integer} Suggest a preferred position for this result
+ within the result set. Undefined if none.
+ isSuggestedIndexRelativeToGroup: {boolean} Whether the suggestedIndex
+ property is relative to the result's group
+ instead of the entire result set.
+ }
+
+The following RESULT_TYPEs are supported:
+
+.. highlight:: JavaScript
+.. code::
+
+ // An open tab.
+ // Payload: { icon, url, userContextId }
+ TAB_SWITCH: 1,
+ // A search suggestion or engine.
+ // Payload: { icon, suggestion, keyword, query, providesSearchMode, inPrivateWindow, isPrivateEngine }
+ SEARCH: 2,
+ // A common url/title tuple, may be a bookmark with tags.
+ // Payload: { icon, url, title, tags }
+ URL: 3,
+ // A bookmark keyword.
+ // Payload: { icon, url, keyword, postData }
+ KEYWORD: 4,
+ // A WebExtension Omnibox result.
+ // Payload: { icon, keyword, title, content }
+ OMNIBOX: 5,
+ // A tab from another synced device.
+ // Payload: { icon, url, device, title }
+ REMOTE_TAB: 6,
+ // An actionable message to help the user with their query.
+ // Payload: { buttons, helpL10n, helpUrl, icon, titleL10n, type }
+ TIP: 7,
+ // A type of result created at runtime, for example by an extension.
+ // Payload: { dynamicType }
+ DYNAMIC: 8,