1Utilities for implementing APIs 2=============================== 3 4This page covers some utility classes that are useful for 5implementing WebExtension APIs: 6 7WindowManager 8------------- 9This class manages the mapping between the opaque window identifiers used 10in the `browser.windows <https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/windows>`__ API. 11See the reference docs `here <reference.html#windowmanager-class>`__. 12 13TabManager 14---------- 15This class manages the mapping between the opaque tab identifiers used 16in the `browser.tabs <https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs>`__ API. 17See the reference docs `here <reference.html#tabmanager-class>`__. 18 19ExtensionSettingsStore 20---------------------- 21ExtensionSettingsStore (ESS) is used for storing changes to settings that are 22requested by extensions, and for finding out what the current value 23of a setting should be, based on the precedence chain or a specific selection 24made (typically) by the user. 25 26When multiple extensions request to make a change to a particular 27setting, the most recently installed extension will be given 28precedence. 29 30It is also possible to select a specific extension (or no extension, which 31infers user-set) to control a setting. This will typically only happen via 32ExtensionPreferencesManager described below. When this happens, precedence 33control is not used until either a new extension is installed, or the controlling 34extension is disabled or uninstalled. If user-set is specifically chosen, 35precedence order will only be returned to by installing a new extension that 36takes control of the setting. 37 38ESS will manage what has control over a setting through any 39extension state changes (ie. install, uninstall, enable, disable). 40 41Notifications: 42^^^^^^^^^^^^^^ 43 44"extension-setting-changed": 45**************************** 46 47 When a setting changes an event is emitted via the apiManager. It contains 48 the following: 49 50 * *action*: one of select, remove, enable, disable 51 52 * *id*: the id of the extension for which the setting has changed, may be null 53 if the setting has returned to default or user set. 54 55 * *type*: The type of setting altered. This is defined by the module using ESS. 56 If the setting is controlled through the ExtensionPreferencesManager below, 57 the value will be "prefs". 58 59 * *key*: The name of the setting altered. 60 61 * *item*: The new value, if any that has taken control of the setting. 62 63 64ExtensionPreferencesManager 65--------------------------- 66ExtensionPreferencesManager (EPM) is used to manage what extensions may control a 67setting that results in changing a preference. EPM adds additional logic on top 68of ESS to help manage the preference values based on what is in control of a 69setting. 70 71Defining a setting in an API 72^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 73 74A preference setting is defined in an API module by calling EPM.addSetting. addSetting 75allows the API to use callbacks that can handle setting preferences as needed. Since 76the setting is defined at runtime, the API module must be loaded as necessary by EPM 77to properly manage settings. 78 79In the api module definition (e.g. ext-toolkit.json), the api must use `"settings": true` 80so the management code can discover which API modules to load in order to manage a 81setting. See browserSettings[1] as an example. 82 83Settings that are exposed to the user in about:preferences also require special handling. 84We typically show that an extension is in control of the preference, and prevent changes 85to the setting. Some settings may allow the user to choose which extension (or none) has 86control of the setting. 87 88Preferences behavior 89^^^^^^^^^^^^^^^^^^^^ 90 91To actually set a setting, the module must call EPM.setSetting. This is typically done 92via an extension API, such as browserSettings.settingName.set({ ...value data... }), though 93it may be done at other times, such as during extension startup or install in a modules 94onManifest handler. 95 96Preferences are not always changed when an extension uses an API that results in a call 97to EPM.setSetting. When setSetting is called, the values are stored by ESS (above), and if 98the extension currently has control, or the setting is controllable by the extension, then 99the preferences would be updated. 100 101The preferences would also potentially be updated when installing, enabling, disabling or 102uninstalling an extension, or by a user action in about:preferences (or other UI that 103allows controlling the preferences). If all extensions that use a preference setting are 104disabled or uninstalled, the prior user-set or default values would be returned to. 105 106An extension may watch for changes using the onChange api (e.g. browserSettings.settingName.onChange). 107 108[1] https://searchfox.org/mozilla-central/rev/04d8e7629354bab9e6a285183e763410860c5006/toolkit/components/extensions/ext-toolkit.json#19 109 110Notifications: 111^^^^^^^^^^^^^^ 112 113"extension-setting-changed:*name*": 114*********************************** 115 116 When a setting controlled by EPM changes an event is emitted via the apiManager. It contains 117 no other data. This is used primarily to implement the onChange API. 118 119ESS vs. EPM 120----------- 121An API may use ESS when it needs to allow an extension to store a setting value that 122affects how Firefox works, but does not result in setting a preference. An example 123is allowing an extension to change the newTab value in the newTab service. 124 125An API should use EPM when it needs to allow an extension to change a preference. 126 127Using ESS/EPM with experimental APIs 128------------------------------------ 129 130Properly managing settings values depends on the ability to load any modules that 131define a setting. Since experimental APIs are defined inside the extension, there 132are situations where settings defined in experimental APIs may not be correctly 133managed. The could result in a preference remaining set by the extension after 134the extension is disabled or installed, especially when that state is updated during 135safe mode. 136 137Extensions making use of settings in an experimental API should practice caution, 138potentially unsetting the values when the extension is shutdown. Values used for 139the setting could be stored in the extensions locale storage, and restored into 140EPM when the extension is started again. 141