Geolocation provides access to geographical location information associated with the hosting device.

Since this specification become a W3C Recommendation on 01 September 2022, the following substantive additions and/or corrections have been proposed:

A more detailed list of changes can be found in section [[[#changelog]]]. Reviewers of the document can identify candidate additions and/or corrections by their distinctive styling in the document.

Introduction

Geolocation defines a high-level interface to location information associated only with the device hosting the implementation. Common sources of location information include Global Positioning System (GPS) and location inferred from network signals such as IP address, RFID, WiFi and Bluetooth MAC addresses, and GSM/CDMA cell IDs, as well as user input. The API itself is agnostic of the underlying location information sources, and no guarantee is given that the API returns the device's actual location.

If an end user [=check permission|grants permission=], Geolocation:

Scope

This specification is limited to providing a scripting API for retrieving geographic position information associated with a hosting device. The geographic position information is provided in terms of World Geodetic System coordinates [[WGS84]]. It does not include providing a markup language of any kind, nor does not include defining a new URL scheme for building URLs that identify geographic locations.

Examples

The API is designed to enable both "one-shot" position requests and repeated position updates. The following examples illustrate common use cases.

Get current position

Request the user's current location. If the user allows it, you will get back a position object.

Watch a position

Request the ability to watch user's current location. If the user allows it, you will get back continuous updates of the user's position.

Stop watching a position

Stop watching for position changes by calling the {{Geolocation/clearWatch()}} method.

Handling errors

When an error occur, the second argument of the {{Geolocation/watchPosition()}} or {{Geolocation/getCurrentPosition()}} method gets called with a {{GeolocationPositionError}} error, which can help you figure out what might have gone wrong.

Using `maximumAge` as cache control

By default, the API always attempts to return a cached position so long as it has a previously acquired position. In this example, we accept a position whose age is no greater than 10 minutes. If the user agent does not have a fresh enough cached position object, it automatically acquires a new position.

Using `timeout`

If you require location information in a time sensitive manner, you can use the {{PositionOptions}} {{PositionOptions/timeout}} member to limit the amount of time you are willing to wait to [=acquire a position=].

Enabling the API in third-party contexts

The [=policy-controlled feature/default allowlist=] of `'self'` allows API usage in same-origin nested frames but prevents third-party content from using the API.

Third-party usage can be selectively enabled by adding the [^iframe/allow^]`="geolocation"` attribute to an [^iframe^] element:

Alternatively, the API can be disabled in a first-party context by specifying an HTTP response header:

See [[[permissions-policy]]] for more details about the `Permissions-Policy` HTTP header.

Privacy considerations

The API defined in this specification is used to retrieve the geographic location of a hosting device. In almost all cases, this information also discloses the location of the user of the device, thereby potentially compromising the user's privacy.

User consent

Geolocation is a [=powerful feature=] that requires [=express permission=] from an end-user before any location data is shared with a web application. This requirement is normatively enforced by the [=check permission=] steps on which the {{Geolocation/getCurrentPosition()}} and {{Geolocation/watchPosition()}} methods rely.

An end-user will generally give [=express permission=] through a user interface, which usually present a range of permission [=permission/lifetimes=] that the end-user can choose from. The choice of [=permission/lifetimes=] vary across user agents, but they are typically time-based (e.g., "a day"), or until browser is closed, or the user might even be given the choice for the permission to be granted indefinitely. The permission [=permission/lifetimes=] dictate how long a user agent [=permission/grants=] a permission before that permission is automatically reverted back to its default [=permission state=], prompting the end-user to make a new choice upon subsequent use.

Although the granularity of the permission [=permission/lifetime=] varies across user-agents, this specification urges user agents to limit the lifetime to a single browsing session by default (see [[[#check-permission]]] for normative requirements).

Privacy considerations for recipients of location information

This section applies to "recipients", which generally means developers utilizing Geolocation. Although it's impossible for the user agent, or this specification, to enforce these requirements, developers need to read this section carefully and do their best to adhere to the suggestions below. Developers need to be aware that there might be privacy laws in their jurisdictions that can govern the usage and access to users' location data.

Recipients ought to only request position information when necessary, and only use the location information for the task for which it was provided to them. Recipients ought to dispose of location information once that task is completed, unless expressly permitted to retain it by the user. Recipients need to also take measures to protect this information against unauthorized access. If location information is stored, users need to be allowed to update and delete this information.

The recipients of location information need to refrain from retransmitting the location information without the user’s express permission. Care needs to be taken when retransmitting and the use of encryption is encouraged.

Recipients ought to clearly and conspicuously disclose the fact that they are collecting location data, the purpose for the collection, how long the data is retained, how the data is secured, how the data is shared if it is shared, how users can access, update and delete the data, and any other choices that users have with respect to the data. This disclosure needs to include an explanation of any exceptions to the guidelines listed above.

Implementation considerations

Implementers are advised to consider the following aspects that can negatively affect the privacy of their users: in certain cases, users can inadvertently grant permission to the user agent to disclose their location to websites. In other cases, the content hosted at a certain URL changes in such a way that the previously granted location permissions no longer apply as far as the user is concerned. Or the users might simply change their minds.

Predicting or preventing these situations is inherently difficult. Mitigation and in-depth defensive measures are an implementation responsibility and not prescribed by this specification. However, in designing these measures, implementers are advised to enable user awareness of location sharing, and to provide access to user interfaces that enable revocation of permissions.

Checking permission to use the API

Geolocation is a [=default powerful feature=] identified by the [=powerful feature/name=] "geolocation".

When checking permission to use the API, a user agent MAY suggest time-based [=permission=] [=permission/lifetimes=], such as "24 hours", "1 week", or choose to remember the permission [=permission/grant=] indefinitely. However, it is RECOMMENDED that a user agent prioritize restricting the [=permission=] [=permission/lifetime=] to a single session: This can be, for example, until the [=environment settings object/realm=] is destroyed, the end-user [=navigates=] away from the [=origin=], or the relevant browser tab is closed.

Security considerations

There are no security considerations associated with Geolocation at the time of publication. However, readers are advised to read the [[[#privacy]]].

`Geolocation` interface and callbacks

        [Exposed=Window]
        interface Geolocation {
          undefined getCurrentPosition (
            PositionCallback successCallback,
            optional PositionErrorCallback? errorCallback = null,
            optional PositionOptions options = {}
          );

          long watchPosition (
            PositionCallback successCallback,
            optional PositionErrorCallback? errorCallback = null,
            optional PositionOptions options = {}
          );

          undefined clearWatch (long watchId);
        };

        callback PositionCallback = undefined (
          GeolocationPosition position
        );

        callback PositionErrorCallback = undefined (
          GeolocationPositionError positionError
        );
      

Internal slots

Instances of {{Geolocation}} are created with the internal slots in the following table:

Internal slot Description
[[\cachedPosition]] A {{GeolocationPosition}}, initialized to null. It's a reference to the last acquired position and serves as a cache. A user agent MAY evict {{Geolocation/[[cachedPosition]]}} by resetting it to null at any time for any reason.
[[\watchIDs]] Initialized as an empty [=list=] of {{unsigned long}} [=list/item|items=].

`getCurrentPosition()` method

The getCurrentPosition(|successCallback:PositionCallback|, |errorCallback:PositionErrorCallback?|, |options:PositionOptions|) method steps are:

  1. If the [=current settings object=]'s [=relevant global object=]'s [=associated `Document`=] is not [=Document/fully active=]: If [=this=]'s [=relevant global object=]'s [=associated `Document`=] is not [=Document/fully active=]:
    1. [=Call back with error=] |errorCallback| and {{GeolocationPositionError/POSITION_UNAVAILABLE}}.
    2. Terminate this algorithm.
  2. [=Request a position=] passing [=this=], |successCallback|, |errorCallback|, and |options|.

`watchPosition()` method

The watchPosition(|successCallback:PositionCallback|, |errorCallback:PositionErrorCallback?|, |options:PositionOptions|) method steps are:

  1. If the [=current settings object=]'s [=relevant global object=]'s [=associated `Document`=] is not [=Document/fully active=]: If [=this=]'s [=relevant global object=]'s [=associated `Document`=] is not [=Document/fully active=]:
    1. [=Call back with error=] passing |errorCallback| and {{GeolocationPositionError/POSITION_UNAVAILABLE}}.
    2. Return 0.
  2. Let |watchId:unsigned long| be an [=implementation-defined=] {{unsigned long}} that is greater than zero.
  3. [=List/Append=] |watchId| to [=this=]'s {{Geolocation/[[watchIDs]]}}.
  4. [=Request a position=] passing [=this=], |successCallback|, |errorCallback|, |options|, and |watchId|.
  5. Return |watchId|.

`clearWatch()` method

When clearWatch() is invoked, the user agent MUST:

  1. [=List/Remove=] |watchId| from [=this=]'s {{Geolocation/[[watchIDs]]}}.

Request a position

To request a position, pass a {{Geolocation}} |geolocation:Geolocation|, a {{PositionCallback}} |successCallback:PositionCallback|, a {{PositionErrorCallback?}} |errorCallback:PositionErrorCallback?|, a {{PositionOptions}} |options:PositionOptions|, and an optional |watchId:unsigned long|:

  1. Let |watchIDs:List| be |geolocation|'s {{Geolocation/[[watchIDs]]}}.
  2. Let |document:Document| be the |geolocation|'s [=relevant global object=]'s [=associated `Document`=].
  3. If |document| is not [=allowed to use=] the "geolocation" feature:
    1. If |watchId| was passed, [=List/remove=] |watchId| from |watchIDs|.
    2. [=Call back with error=] passing |errorCallback| and {{GeolocationPositionError/PERMISSION_DENIED}}.
    3. Terminate this algorithm.
  4. If |geolocation|'s [=environment settings object=] is a [=non-secure context=]:
    1. If |watchId| was passed, [=List/remove=] |watchId| from |watchIDs|.
    2. [=Call back with error=] passing |errorCallback| and {{GeolocationPositionError/PERMISSION_DENIED}}.
    3. Terminate this algorithm.
  5. If |document:Document|'s [=Document/visibility state=] is "hidden", wait for the following [=page visibility change steps=] to run:
    1. Assert: |document|'s [=Document/visibility state=] is "visible".
    2. Continue to the next steps below.
  6. Let |descriptor| be a new {{PermissionDescriptor}} whose {{PermissionDescriptor/name}} is "geolocation".
  7. [=In parallel=]:
    1. Set |permission| to [=request permission to use=] |descriptor|.
    2. If |permission| is "denied", then:
      1. If |watchId| was passed, [=list/remove=] |watchId| from |watchIDs|.
      2. [=Call back with error=] passing |errorCallback| and {{GeolocationPositionError/PERMISSION_DENIED}}.
      3. Terminate this algorithm.
    3. Wait to [=acquire a position=] passing |successCallback|, |errorCallback|, |options|, and |watchId|.
    4. If |watchId| was not passed, terminate this algorithm.
    5. While |watchIDs| [=list/contains=] |watchId|:
      1. Wait for a significant change of geographic position. What constitutes a significant change of geographic position is left to the implementation. User agents MAY impose a rate limit on how frequently position changes are reported. User agents MUST consider invoking [=set emulated position data=] as a significant change.
      2. If |document| is not [=Document/fully active=] or [=Document/visibility state=] is not "visible", go back to the previous step and again wait for a significant change of geographic position.
      3. Wait to [=acquire a position=] passing |successCallback|, |errorCallback|, |options|, and |watchId|.

Acquire a position

To acquire a position, passing {{PositionCallback}} |successCallback:PositionCallback|, a {{PositionErrorCallback?}} |errorCallback:PositionErrorCallback?|, {{PositionOptions}} |options:PositionOptions|, and an optional |watchId:unsigned long|.

  1. If |watchId| was passed and [=this=]'s {{Geolocation/[[watchIDs]]}} does not [=list/contain=] |watchId|, terminate this algorithm.
  2. Let |acquisitionTime:EpochTimeStamp| be a new {{EpochTimeStamp}} that represents now.
  3. Let |timeoutTime| be the sum of |acquisitionTime| and |options|.{{PositionOptions/timeout}}.
  4. Let |cachedPosition:GeolocationPosition| be [=this=]'s {{Geolocation/[[cachedPosition]]}}.
  5. Create an implementation-specific |timeout| task that elapses at |timeoutTime|, during which it tries to acquire the device's position by running the following steps:
    1. Let |permission| be [=get the current permission state=] of "geolocation".
    2. If |permission| is "denied":
      1. Stop |timeout|.
      2. Do the user or system denied permission failure case step.
    3. If |permission| is "granted":
      1. Check if an emulated position should be used by running the following steps:
        1. Let |emulatedPositionData| be [=get emulated position data=] passing [=this=].
        2. If |emulatedPositionData| is not null:
          1. If |emulatedPositionData| is a {{GeolocationPositionError}}:
            1. [=Call back with error=] passing |errorCallback| and |emulatedPositionData|.
            2. Terminate this algorithm.
          2. Let |position| be [=a new `GeolocationPosition`=] passing |emulatedPositionData|, |acquisitionTime| and |options|.{{PositionOptions/enableHighAccuracy}}.
          3. [=Queue a task=] on the [=geolocation task source=] with a step that [=invokes=] |successCallback| with « |position| » and "`report`".
          4. Terminate this algorithm.
      2. Let |position| be null.
      3. If |cachedPosition| is not null, and |options|.{{PositionOptions/maximumAge}} is greater than 0:
        1. Let |cacheTime:long| be |acquisitionTime| minus the value of the |options|.{{PositionOptions/maximumAge}} member.
        2. If |cachedPosition|'s {{GeolocationPosition/timestamp}}'s value is greater than |cacheTime|, and |cachedPosition|.{{GeolocationPosition/[[isHighAccuracy]]}} equals |options|.{{PositionOptions/enableHighAccuracy}}, set |position| to |cachedPosition|. :
          1. [=Queue a task=] on the [=geolocation task source=] with a step that [=invokes=] |successCallback| with « |cachedPosition| » and "`report`".
          2. Terminate this algorithm.
      4. Otherwise, if |position| is not |cachedPosition|, try to acquire position data from the underlying system, optionally taking into consideration the value of |options|.{{PositionOptions/enableHighAccuracy}} during acquisition.
      5. If the |timeout| elapses during acquisition, or acquiring the device's position results in failure:
        1. Stop the |timeout|.
        2. Go to dealing with failures.
        3. Terminate this algorithm.
      6. If acquiring the position data from the system succeeds:
        1. Let |positionData| be a [=map=] with the following name/value pairs based on the acquired position data:
          "longitude"
          A {{double}} that represents the longitude coordinates on the Earth's surface in degrees, using the [[WGS84]] coordinate system. Longitude measures how far east or west a point is from the Prime Meridian.
          "altitude"
          A {{double?}} that represents the altitude in meters above the [[WGS84]] ellipsoid, or `null` if not available. Altitude measures the height above sea level.
          "accuracy"
          A non-negative {{double}} that represents the accuracy value indicating the 95% confidence level in meters. Accuracy measures how close the measured coordinates are to the true position.
          "altitudeAccuracy"
          A non-negative {{double?}} that represents the altitude accuracy, or `null` if not available, indicating the 95% confidence level in meters. Altitude accuracy measures how close the measured altitude is to the true altitude.
          "speed"
          A non-negative {{double?}} that represents the speed in meters per second, or `null` if not available. Speed measures how fast the device is moving.
          "heading"
          A {{double?}} that represents the heading in degrees, or `null` if not available or the device is stationary. Heading measures the direction in which the device is moving relative to true north.
        2. Set |position| to [=a new `GeolocationPosition`=] passing |positionData|, |acquisitionTime| and |options|.{{PositionOptions/enableHighAccuracy}}.
        3. Set [=this=]'s {{Geolocation/[[cachedPosition]]}} to |position|.
        1. Set |position| to [=a new `GeolocationPosition`=] passing |acquisitionTime| and |options|.{{PositionOptions/enableHighAccuracy}}.
        2. Set [=this=]'s {{Geolocation/[[cachedPosition]]}} to |position|.
      7. Stop the |timeout|.
      8. [=Queue a task=] on the [=geolocation task source=] with a step that [=invokes=] |successCallback| with « |position| » and "`report`".
    Dealing with failures:
    • If acquiring a position fails, do one of the following based on the condition that matches the failure:
      User or system denied permission:

      [=Call back with error=] passing |errorCallback| and {{GeolocationPositionError/PERMISSION_DENIED}}.

      Timeout elapsed:
      [=Call back with error=] with |errorCallback| and {{GeolocationPositionError/TIMEOUT}}.
      Data acquisition error or any other reason:
      [=Call back with error=] passing |errorCallback| and {{GeolocationPositionError/POSITION_UNAVAILABLE}}.

Call back with error

When instructed to call back with error, given an {{PositionErrorCallback?}} |callback:PositionErrorCallback?| and an {{unsigned short}} |code:unsigned short|:

  1. If |callback| is null, return.
  2. Let |error:GeolocationPositionError| be a newly created {{GeolocationPositionError}} instance whose {{GeolocationPositionError/code}} attribute is initialized to |code|.
  3. [=Queue a task=] on the [=geolocation task source=] with a step that [=invokes=] |callback| with « |error| » and "`report`".

PositionOptions dictionary

        dictionary PositionOptions {
          boolean enableHighAccuracy = false;
          [Clamp] unsigned long timeout = 0xFFFFFFFF;
          [Clamp] unsigned long maximumAge = 0;
        };
        

`enableHighAccuracy` member

The enableHighAccuracy member provides a hint that the application would like to receive the most accurate location data. The intended purpose of this member is to allow applications to inform the implementation that they do not require high accuracy geolocation fixes and, therefore, the implementation MAY avoid using geolocation providers that consume a significant amount of power (e.g., GPS).

`timeout` member

The timeout member denotes the maximum length of time, expressed in milliseconds, before [=acquiring a position=] expires.

The time spent waiting for the document to become visible and for [=check permission|obtaining permission to use the API=] is not included in the period covered by the {{PositionOptions/timeout}} member. The {{PositionOptions/timeout}} member only applies when [=acquiring a position=] begins.

`maximumAge` member

The maximumAge member indicates that the web application is willing to accept a cached position whose age is no greater than the specified time in milliseconds.

`GeolocationPosition` interface

        [Exposed=Window, SecureContext]
        interface GeolocationPosition {
          readonly attribute GeolocationCoordinates coords;
          readonly attribute EpochTimeStamp timestamp;
          [Default] object toJSON();
        };
      

`coords` attribute

The coords attribute contains geographic coordinates.

`timestamp` attribute

The timestamp attribute represents the time when the geographic position of the device was acquired.

`toJSON()` method

The toJSON() method returns a JSON representation of the {{GeolocationPosition}} object.

Internal slots

Instances of {{GeolocationPositionError}} are created with the internal slots in the following table:

Internal slot Description
[[\isHighAccuracy]] A {{boolean}} that records the value of the {{PositionOptions/enableHighAccuracy}} member when this {{GeolocationPosition}} is [=a new GeolocationPosition|created=].

Task sources

The following [=task source=] is defined by this specifications.

The geolocation task source
Used by this specification to queue up non-blocking {{PositionCallback}} and {{PositionErrorCallback}} when performing [=request a position|position requests=].

GeolocationCoordinates interface

        [Exposed=Window, SecureContext]
        interface GeolocationCoordinates {
          readonly attribute double accuracy;
          readonly attribute double latitude;
          readonly attribute double longitude;
          readonly attribute double? altitude;
          readonly attribute double? altitudeAccuracy;
          readonly attribute double? heading;
          readonly attribute double? speed;
          [Default] object toJSON();
        };
      

`latitude`, `longitude`, and `accuracy` attributes

The latitude and longitude attributes are geographic coordinates specified in decimal degrees. The latitude and longitude attributes denote the position, specified as a real number of degrees, in the [[WGS84]] coordinate system. The accuracy attribute denotes the position accuracy radius in meters.

`altitude` and `altitudeAccuracy` attributes

The altitude attribute denotes the height of the position, specified in meters above the [[WGS84]] ellipsoid.

The altitudeAccuracy attribute represents the altitude accuracy in meters (e.g., `10` meters).

`heading` attribute

The heading attribute denotes the direction of travel of the hosting device and is specified in degrees, where 0° ≤ heading < 360°, counting clockwise relative to the true north.

`speed` attribute

The speed attribute denotes the magnitude of the horizontal component of the hosting device's current velocity in meters per second.

`toJSON()` method

The toJSON() method returns a JSON representation of the {{GeolocationCoordinates}} object.

Constructing a `GeolocationPosition`

A new `GeolocationPosition` is constructed with [=map=] |positionData|, {{EpochTimeStamp}} |timestamp:EpochTimeStamp| and boolean |isHighAccuracy| by performing the following steps:

  1. Let |coords:GeolocationCoordinates| be a newly created {{GeolocationCoordinates}} instance.
  2. [=map/For each=] |key| → |value| in |positionData|:
    1. Set |coords|'s attribute named |key| to |value|.
  3. Return a newly created {{GeolocationPosition}} instance with its {{GeolocationPosition/coords}} attribute initialized to |coords| and {{GeolocationPosition/timestamp}} attribute initialized to |timestamp|, and its {{GeolocationPosition/[[isHighAccuracy]]}} internal slot set to |isHighAccuracy|.

A new `GeolocationPosition` is constructed with {{EpochTimeStamp}} |timestamp:EpochTimeStamp| and boolean |isHighAccuracy| by performing the following steps:

  1. Let |coords:GeolocationCoordinates| be a newly created {{GeolocationCoordinates}} instance:
    1. Initialize |coord|'s {{GeolocationCoordinates/latitude}} attribute to a geographic coordinate in decimal degrees.
    2. Initialize |coord|'s {{GeolocationCoordinates/longitude}} attribute to a geographic coordinate in decimal degrees.
    3. Initialize |coord|'s {{GeolocationCoordinates/accuracy}} attribute to a non-negative real number. The value SHOULD correspond to a 95% confidence level with respect to the longitude and latitude values.
    4. Initialize |coord|'s {{GeolocationCoordinates/altitude}} attribute in meters above the [[WGS84]] ellipsoid, or `null` if the implementation cannot provide altitude information.
    5. Initialize |coord|'s {{GeolocationCoordinates/altitudeAccuracy}} attribute as non-negative real number, or to `null` if the implementation cannot provide altitude information. If the altitude accuracy information is provided, it SHOULD correspond to a 95% confidence level.
    6. Initialize |coord|'s {{GeolocationCoordinates/speed}} attribute to a non-negative real number, or as `null` if the implementation cannot provide speed information.
    7. Initialize |coord|'s {{GeolocationCoordinates/heading}} attribute in degrees, or `null` if the implementation cannot provide heading information. If the hosting device is stationary (i.e., the value of the {{GeolocationCoordinates/speed}} attribute is 0), then initialize the {{GeolocationCoordinates/heading}} to `NaN`.
  2. Return a newly created {{GeolocationPosition}} instance with its {{GeolocationPosition/coords}} attribute initialized to |coords| and {{GeolocationPosition/timestamp}} attribute initialized to |timestamp|, and its {{GeolocationPosition/[[isHighAccuracy]]}} internal slot set to |isHighAccuracy|.

GeolocationPositionError interface

        [Exposed=Window]
        interface GeolocationPositionError {
          const unsigned short PERMISSION_DENIED = 1;
          const unsigned short POSITION_UNAVAILABLE = 2;
          const unsigned short TIMEOUT = 3;
          readonly attribute unsigned short code;
          readonly attribute DOMString message;
        };
        

Constants

PERMISSION_DENIED (numeric value 1)
[=Request a position=] failed because the user denied permission to use the API or the request was made from an [=non-secure context=].
POSITION_UNAVAILABLE (numeric value 2)
[=Acquire a position=] failed.
TIMEOUT (numeric value 3)
The length of time specified by the {{PositionOptions/timeout}} member has elapsed before the user agent could successfully [=acquire a position=].

`code` attribute

The code attribute returns the value it was [=call back with error|initialized to=] (see [[[#constants]]] for possible values).

`message` attribute

The message attribute is a developer-friendly textual description of the {{GeolocationPositionError/code}} attribute.

Permissions policy

This specification defines a [=policy-controlled feature=] identified by the token string "geolocation". Its [=policy-controlled feature/default allowlist=] is [=default allowlist/'self'=].

Emulation

For the purposes of user-agent automation and application testing, this document defines geolocation emulations.

Each [=top-level traversable=] has an associated emulated position data, which is data representing {{GeolocationCoordinates}}, {{GeolocationPositionError}} or null, initially null.

To set emulated position data, given [=navigable=] |navigable| and an |emulatedPositionData|:

  1. Assert |emulatedPositionData| is either null, a {{GeolocationCoordinates}}, or a {{GeolocationPositionError}}.
  2. Let |traversable| be |navigable|’s [=navigable/top-level traversable=].
  3. If |traversable| is not null:
    1. Set |traversable|'s associated [=emulated position data=] to |emulatedPositionData|.
    2. User agents MUST consider this as a "significant change" in the wait for a significant change of geographic position step.

To get emulated position data, given {{Geolocation}} |geolocation|:

  1. Let |navigable| be |geolocation|'s [=relevant global object=]'s [=associated `Document`=]'s [=node navigable=].
  2. If |navigable| is null, return null.
  3. Let |traversable| be |navigable|’s [=navigable/top-level traversable=].
  4. If |traversable| is null, return null.
  5. Return |traversable|'s associated [=emulated position data=].

Acknowledgments

This specification builds upon earlier work in the industry, including research by Aza Raskin, Google Gears Geolocation API, and LocationAware.org.

Thanks also to Alec Berntson, Alissa Cooper, Steve Block, Greg Bolsinga, Lars Erik Bolstad, Aaron Boodman, Dave Burke, Chris Butler, Max Froumentin, Shyam Habarakada, Marcin Hanclik, Ian Hickson, Brad Lassey, Angel Machin, Cameron McCormack, Daniel Park, Stuart Parmenter, Olli Pettay, Chris Prince, Arun Ranganathan, Carl Reed, Thomas Roessler, Dirk Segers, Allan Thomson, Martin Thomson, Doug Turner, Erik Wilde, Matt Womer, and Mohamed Zergaoui.

Change log

Since First Public Working Draft in 2021, Geolocation has received the following normative changes:

Since publication of the Second Edition in 2016, this specification received the following substantive changes:

See the commit history for a complete list of changes.