forked from mirrors/gecko-dev
		
	 642c253a90
			
		
	
	
		642c253a90
		
	
	
	
	
		
			
			Differential Revision: https://phabricator.services.mozilla.com/D55846 --HG-- extra : moz-landing-system : lando
		
			
				
	
	
		
			140 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| Utilities for implementing APIs
 | |
| ===============================
 | |
| 
 | |
| This page covers some utility classes that are useful for
 | |
| implementing WebExtension APIs:
 | |
| 
 | |
| WindowManager
 | |
| -------------
 | |
| This class manages the mapping between the opaque window identifiers used
 | |
| in the `browser.windows <https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/windows>`__ API.
 | |
| See the reference docs `here <reference.html#windowmanager-class>`__.
 | |
| 
 | |
| TabManager
 | |
| ----------
 | |
| This class manages the mapping between the opaque tab identifiers used
 | |
| in the `browser.tabs <https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs>`__ API.
 | |
| See the reference docs `here <reference.html#tabmanager-class>`__.
 | |
| 
 | |
| ExtensionSettingsStore
 | |
| ----------------------
 | |
| ExtensionSettingsStore (ESS) is used for storing changes to settings that are
 | |
| requested by extensions, and for finding out what the current value
 | |
| of a setting should be, based on the precedence chain or a specific selection
 | |
| made (typically) by the user.
 | |
| 
 | |
| When multiple extensions request to make a change to a particular
 | |
| setting, the most recently installed extension will be given
 | |
| precedence.
 | |
| 
 | |
| It is also possible to select a specific extension (or no extension, which
 | |
| infers user-set) to control a setting.  This will typically only happen via
 | |
| ExtensionPreferencesManager described below.  When this happens, precedence
 | |
| control is not used until either a new extension is installed, or the controlling
 | |
| extension is disabled or uninstalled.  If user-set is specifically chosen,
 | |
| precedence order will only be returned to by installing a new extension that
 | |
| takes control of the setting.
 | |
| 
 | |
| ESS will manage what has control over a setting through any
 | |
| extension state changes (ie. install, uninstall, enable, disable).
 | |
| 
 | |
| Notifications:
 | |
| ^^^^^^^^^^^^^^
 | |
| 
 | |
| "extension-setting-changed":
 | |
| ****************************
 | |
| 
 | |
|   When a setting changes an event is emitted via the apiManager. It contains
 | |
|   the following:
 | |
| 
 | |
|   * *action*: one of select, remove, enable, disable
 | |
| 
 | |
|   * *id*: the id of the extension for which the setting has changed, may be null
 | |
|     if the setting has returned to default or user set.
 | |
| 
 | |
|   * *type*: The type of setting altered.  This is defined by the module using ESS.
 | |
|     If the setting is controlled through the ExtensionPreferencesManager below,
 | |
|     the value will be "prefs".
 | |
| 
 | |
|   * *key*: The name of the setting altered.
 | |
| 
 | |
|   * *item*: The new value, if any that has taken control of the setting.
 | |
| 
 | |
| 
 | |
| ExtensionPreferencesManager
 | |
| ---------------------------
 | |
| ExtensionPreferencesManager (EPM) is used to manage what extensions may control a
 | |
| setting that results in changing a preference.  EPM adds additional logic on top
 | |
| of ESS to help manage the preference values based on what is in control of a
 | |
| setting.
 | |
| 
 | |
| Defining a setting in an API
 | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | |
| 
 | |
| A preference setting is defined in an API module by calling EPM.addSetting.  addSetting
 | |
| allows the API to use callbacks that can handle setting preferences as needed.  Since
 | |
| the setting is defined at runtime, the API module must be loaded as necessary by EPM
 | |
| to properly manage settings.
 | |
| 
 | |
| In the api module definition (e.g. ext-toolkit.json), the api must use `"settings": true`
 | |
| so the management code can discover which API modules to load in order to manage a
 | |
| setting.  See browserSettings[1] as an example.
 | |
| 
 | |
| Settings that are exposed to the user in about:preferences also require special handling.
 | |
| We typically show that an extension is in control of the preference, and prevent changes
 | |
| to the setting.  Some settings may allow the user to choose which extension (or none) has
 | |
| control of the setting.
 | |
| 
 | |
| Preferences behavior
 | |
| ^^^^^^^^^^^^^^^^^^^^
 | |
| 
 | |
| To actually set a setting, the module must call EPM.setSetting.  This is typically done
 | |
| via an extension API, such as browserSettings.settingName.set({ ...value data... }), though
 | |
| it may be done at other times, such as during extension startup or install in a modules
 | |
| onManifest handler.
 | |
| 
 | |
| Preferences are not always changed when an extension uses an API that results in a call
 | |
| to EPM.setSetting.  When setSetting is called, the values are stored by ESS (above), and if
 | |
| the extension currently has control, or the setting is controllable by the extension, then
 | |
| the preferences would be updated.
 | |
| 
 | |
| The preferences would also potentially be updated when installing, enabling, disabling or
 | |
| uninstalling an extension, or by a user action in about:preferences (or other UI that
 | |
| allows controlling the preferences).  If all extensions that use a preference setting are
 | |
| disabled or uninstalled, the prior user-set or default values would be returned to.
 | |
| 
 | |
| An extension may watch for changes using the onChange api (e.g. browserSettings.settingName.onChange).
 | |
| 
 | |
| [1] https://searchfox.org/mozilla-central/rev/04d8e7629354bab9e6a285183e763410860c5006/toolkit/components/extensions/ext-toolkit.json#19
 | |
| 
 | |
| Notifications:
 | |
| ^^^^^^^^^^^^^^
 | |
| 
 | |
| "extension-setting-changed:*name*":
 | |
| ***********************************
 | |
| 
 | |
|   When a setting controlled by EPM changes an event is emitted via the apiManager. It contains
 | |
|   no other data.  This is used primarily to implement the onChange API.
 | |
| 
 | |
| ESS vs. EPM
 | |
| -----------
 | |
| An API may use ESS when it needs to allow an extension to store a setting value that
 | |
| affects how Firefox works, but does not result in setting a preference.  An example
 | |
| is allowing an extension to change the newTab value in the newTab service.
 | |
| 
 | |
| An API should use EPM when it needs to allow an extension to change a preference.
 | |
| 
 | |
| Using ESS/EPM with experimental APIs
 | |
| ------------------------------------
 | |
| 
 | |
| Properly managing settings values depends on the ability to load any modules that
 | |
| define a setting.  Since experimental APIs are defined inside the extension, there
 | |
| are situations where settings defined in experimental APIs may not be correctly
 | |
| managed.  The could result in a preference remaining set by the extension after
 | |
| the extension is disabled or installed, especially when that state is updated during
 | |
| safe mode.
 | |
| 
 | |
| Extensions making use of settings in an experimental API should practice caution,
 | |
| potentially unsetting the values when the extension is shutdown.  Values used for
 | |
| the setting could be stored in the extensions locale storage, and restored into
 | |
| EPM when the extension is started again.
 |