WebAPI/Navigator.hasFeature
Contents
Use Cases
We have a number of use cases for detecting features in the platform which are not directly detectible through the usual way of feature detection (which is |"foo" in object|) because of various reasons, such as lack of sufficient permissions, or the information not being exposed through other parts of the platform, such as the amount of memory available on the device. This information is useful for Market Place because it needs to figure out whether to offer apps that will not work for the user because of things such as lack of support for a feature, not having enough memory, etc.
Note that the initial implementation of this API will be hidden behind a privilege which will only be available to the MarketPlace app. We're hoping to expose this API to unprivileged contexts once we get more experience with it.
Important note: this is not designed to replace the usual feature detection practices on the Web. This is only intended to address the use cases which are not possible to satisfy using the conventional feature detection techniques because the APIs are hidden behind permissions that the calling code does not possess.
Interface
[NoInterfaceObject] interface NavigatorFeatures { Promise hasFeature(DOMString name); Promise getFeature(DOMString name); }; Navigator implements NavigatorFeatures; WorkerNavigator implements NavigatorFeatures;
Semantics
Both hasFeature and getFeature accept string arguments to denote the feature names. getFeature resolves the promise with an undefined value if the feature name passed to them is unknown. For the "api" and "manifest" namespaces as described below, hasFeature will fullfill the promise with a true value if the feature exists on the "platform" (which means the current state and version of the hardware and the UA software) albeit hidden behind some runtime permissions, and it will fulfill the promise with a false value if the feature doesn't exist on the "platform". The type of that value depends on the feature being queried. The idea is that hasFeature should be used for mere existence tests, and getFeature should be used for queries involving asking more information about a feature, such as the size of something.
The feature name specifies a namespaced value in the following form:
"<namespace_name>.<feature_name>"
The namespace_name part allows for future extensions to this API.
Supported feature names
"hardware" namespace
- hardware.memory
This feature name is used with getFeature, and returns the amount of physical memory available to the OS installed on the device in mebibytes.
"api" namespace
Names under this namespace have this general form: "api.window/worker.InterfaceName.propertyName". These names can be used with hasFeature.
We currently do not support any feature names for the worker context. The following are the names that we support:
- api.window.MozMobileNetworkInfo
- api.window.Navigator.mozBluetooth
- api.window.Navigator.mozContacts
- api.window.Navigator.getDeviceStorage
- api.window.Navigator.addIdleObserver
- api.window.Navigator.mozNetworkStats
- api.window.Navigator.push
- api.window.Navigator.mozTime
- api.window.Navigator.mozFMRadio
- api.window.Navigator.mozCameras
- api.window.Navigator.mozAlarms
- api.window.Navigator.mozTCPSocket
- api.window.Navigator.mozInputMethod
- api.window.Navigator.mozMobileConnections
- api.window.Navigator.getMobileIdAssertion
- api.window.XMLHttpRequest.mozSystem
"manifest" namespace
Names under this namespace have this general form: "manifest.name" or "manifest.name.value". These names can be used with hasFeature.
They are needed to detect whether specifying a field named "name" in the webapp manifest (optionally with a value of "value") will have any effect on the platform. The following names are currently recognized:
- manifest.chrome.navigation
- manifest.origin
- manifest.precompile
- manifest.redirects
Examples
The first example checks to see if we're running on the low-memory Tarako device:
navigator.getFeature("hardware.memory").then(function(mem) { if (mem <= 128) { alert("We are in a memory constrained world!"); } });
The second example checks to see if the privileged FM Radio API is available.
navigator.hasFeature("api.window.Navigator.mozFMRadio").then(function(enabled) { if (enabled) { alert("FM Radio support detected, my privileged app will work!"); } });