RTCRtpSender: getStats() method - Web APIs

RTCRtpSender: getStats() method
===============================

The `RTCRtpSender` method **`getStats()`** asynchronously requests an `RTCStatsReport` object which provides statistics about outgoing traffic on the `RTCPeerConnection` which owns the sender, returning a `Promise` which is fulfilled when the results are available.

Syntax
------

```js
getStats()
```

### Parameters

None.

### Return value

 A JavaScript `Promise` which is fulfilled once the statistics are available.
 The promise's fulfillment handler receives as a parameter a `RTCStatsReport` object containing the collected statistics.

The returned `RTCStatsReport` accumulates the statistics for all of the streams being sent using the `RTCRtpSender`, as well as the statistics for any dependencies those streams have.

These might include, for example, statistics with types: `outbound-rtp`, `candidate-pair`, `local-candidate`, `remote-candidate`.

Examples
--------

This simple example obtains the statistics for an `RTCRtpSender` and updates an element's `innerText` to display the current round trip time for requests on the sender.

```js
sender.getStats().then((stats) => {
  document.getElementById("currentRTT").innerText = stats.roundTripTime;
});
```

Specifications
--------------

| Specification |
| --- |
| WebRTC: Real-Time Communication in Browsers # widl-RTCRtpSender-getStats-Promise-RTCStatsReport |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* WebRTC API
* `RTCStatsReport`
* `RTCRtpReceiver.getStats()`
* `RTCPeerConnection.getStats()`


RTCRtpSender: transport property - Web APIs

RTCRtpSender: transport property
================================

 The read-only **`transport`** property of an
 `RTCRtpSender` object provides the `RTCDtlsTransport` object
 used to interact with the underlying transport over which the sender is exchanging
 Real-time Transport Control Protocol (RTCP) packets.

 This transport is responsible for receiving the data for the media on the sender's
 `track`.

Value
-----

 An `RTCDtlsTransport` object representing the underlying transport being
 used by the sender to exchange packets with the remote peer, or `null` if the
 sender isn't yet connected to a transport.

Description
-----------

 When the `RTCRtpSender` is first created, the value of
 `transport` is `null`. This is replaced with an
 `RTCDtlsTransport` once the sender's transport has been established.

 Note that when bundling is in effect—that is, when the `RTCPeerConnection`
 was created with a configuration object whose `bundlePolicy` is `max-compat`
 or `max-bundle`—multiple senders may be sharing the same transport; in this
 case, all of them are using the same connection to transmit and/or receive
 RTP and RTCP packets.

Specifications
--------------

| Specification |
| --- |
| WebRTC: Real-Time Communication in Browsers # dom-rtcrtpsender-transport |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCRtpSender: getParameters() method - Web APIs

RTCRtpSender: getParameters() method
====================================

The **`getParameters()`** method of the `RTCRtpSender` interface returns an object describing the current configuration for how the sender's `track` will be encoded and transmitted to a remote `RTCRtpReceiver`.

Syntax
------

```js
getParameters()
```

### Parameters

None.

### Return value

An object indicating the current configuration of the sender.

`encodings`

 An array of objects, each specifying the parameters and settings for a single codec that could be used to encode the track's media.
 The properties of the objects include:

`active`

`true` (the default) if the encoding is being sent, `false` if it is not being sent or used.

`dtx`
Deprecated

Non-standard

 Only used for an `RTCRtpSender` whose `kind` is `audio`, this property indicates whether or not discontinuous transmission is being used (a feature by which a phone is turned off or the microphone muted automatically in the absence of voice activity).
 The value is taken either `enabled` or `disabled`.

`maxBitrate`

 A positive integer indicating the maximum number of bits per second that the user agent is allowed to grant to tracks encoded with this encoding.
 Other parameters may further constrain the bit rate, such as the value of `maxFramerate`, or the bandwidth available for the transport or physical network.

The value is computed using the standard Transport Independent Application Specific Maximum (TIAS) bandwidth as defined by RFC 3890, section 6.2.2; this is the maximum bandwidth needed without considering protocol overheads from IP, TCP or UDP, and so forth.

 Note that the bitrate can be achieved in a number of ways, depending on the media and encoding.
 For example, for video a low bit rate might be achieved by dropping frames (a bitrate of zero might allow just one frame to be sent), while for audio the track might have to stop playing if the bitrate is too low for it to be sent.

`maxFramerate`

A value specifying the maximum number of frames per second to allow for this encoding.

`priority`

 A string indicating the priority of the `RTCRtpSender`, which may determine how the user agent allocates bandwidth between senders.
 Allowed values are `very-low`, `low` (default), `medium`, `high`.

`rid`

 A string which, if set, specifies an *RTP stream ID* (*RID*) to be sent using the RID header extension.
 This parameter cannot be modified using `setParameters()`.
 Its value can only be set when the transceiver is first created.

`scaleResolutionDownBy`

 Only used for senders whose track's `kind` is `video`, this is a floating-point value specifying a factor by which to scale down the video during encoding.
 The default value, 1.0, means that the video will be encoded at its original size.
 A value of 2.0 scales the video frames down by a factor of 2 in each dimension, resulting in a video 1/4 the size of the original.
 The value must not be less than 1.0 (attempting to scale the video to a larger size will throw a `RangeError`).

`transactionId`

 A string containing a unique ID.
 This value is used to ensure that `setParameters()` can only be called to modify the parameters returned by a specific previous call to `getParameters()`.
 This parameter cannot be changed by the caller.

`codecs`

 An array of `RTCRtpCodecParameters` objects describing the set of codecs from which the sender or receiver will choose.
 This parameter cannot be changed once initially set.

`headerExtensions`

 An array of zero or more RTP header extensions, each identifying an extension supported by the sender or receiver. Header extensions are described in RFC 3550, section 5.3.1.
 This parameter cannot be changed once initially set.

`rtcp`

 An `RTCRtcpParameters` object providing the configuration parameters used for RTCP on the sender or receiver.
 This parameter cannot be changed once initially set.

`degradationPreference`
Deprecated
 Optional

 Specifies the preferred way the WebRTC layer should handle optimizing bandwidth against quality in constrained-bandwidth situations.
 The possible values are `maintain-framerate`, `maintain-resolution`, or `balanced`.
 The default value is `balanced`.

Examples
--------

This example gets the sender's current transaction ID; the transaction ID uniquely identifies the current set of parameters, to ensure that calls to `setParameters()` are always handled in the correct order, avoiding inadvertently overwriting parameters with older parameters.

```js
function getSenderTransactionID(sender) {
  let parameters = sender.getParameters();

  return parameters.transactionId;
}
```

In the same, way, this code gets the canonical name (CNAME) being used for RTCP on an `RTCRtpSender`.

```js
function getRtpCNAME(sender) {
  let parameters = sender.getParameters();

  return parameters.rtcp.cname;
}
```

Specifications
--------------

| Specification |
| --- |
| WebRTC: Real-Time Communication in Browsers # dom-rtcrtpsender-getparameters |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `RTCRtpSender.setParameters()`
* `RTCRtpReceiver.getParameters()`


FileSystemDirectoryHandle: keys() method - Web APIs

FileSystemDirectoryHandle: keys() method
========================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

 The **`keys()`** method of the
 `FileSystemDirectoryHandle` interface returns a new asynchronous iterator
 for the iteration of the key of the entries within the `FileSystemDirectoryHandle`
 on which this method is called.

Syntax
------

```js
FileSystemDirectoryHandle.keys()
```

### Parameters

None.

### Return value

A new asynchronous iterator containing the keys of each entry within the `FileSystemDirectoryHandle`.

### Exceptions

`NotAllowedError` `DOMException`

Thrown if the `PermissionStatus.state` for the handle is not `'granted'` in `read` mode.

`NotFoundError` `DOMException`

Thrown if the current entry is not found.

Examples
--------

Use the `for await...of` loop can simplify the iteration process.

```js
const dirHandle = await window.showDirectoryPicker();

for await (const key of dirHandle.keys()) {
  console.log(key);
}
```

Specifications
--------------

| Specification |
| --- |
| File System Standard # api-filesystemdirectoryhandle-asynciterable |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* File System API
* The File System Access API: simplifying access to local files


FileSystemDirectoryHandle: getFileHandle() method - Web APIs

FileSystemDirectoryHandle: getFileHandle() method
=================================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

 The **`getFileHandle()`** method of the
 `FileSystemDirectoryHandle` interface returns a
 `FileSystemFileHandle` for a file with the specified name, within the
 directory the method is called.

Syntax
------

```js
getFileHandle(name)
getFileHandle(name, options)
```

### Parameters

`name`

 A string representing the `FileSystemHandle.name` of
 the file you wish to retrieve.

`options` Optional

An object with the following properties:

`create` Optional

 A `Boolean`. Default `false`. When
 set to `true` if the file is not found, one with the specified name
 will be created and returned.

### Return value

A `Promise` which resolves with a `FileSystemFileHandle`.

### Exceptions

`NotAllowedError` `DOMException`

Thrown if the `PermissionStatus.state` for the handle is not `'granted'` in `readwrite` mode if the `create` option is set to `true` or in `read` mode if the `create` option is set to `false`.

`TypeError`

 Thrown if the name specified is not a valid string or contains characters that would
 interfere with the native file system.

`TypeMismatchError` `DOMException`

Thrown if the named entry is a directory and not a file.

`NotFoundError` `DOMException`

 Thrown if the current entry is not found or if the file doesn't exist and the `create` option is set to
 `false`.

Examples
--------

 The following example returns a file handle with the specified name, if the file does
 not exist it is created.

```js
const fileName = "fileToGetName";

// assuming we have a directory handle: 'currentDirHandle'
const fileHandle = currentDirHandle.getFileHandle(fileName, { create: true });
```

Specifications
--------------

| Specification |
| --- |
| File System Standard # api-filesystemdirectoryhandle-getfilehandle |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* File System API
* The File System Access API: simplifying access to local files


FileSystemDirectoryHandle: getDirectoryHandle() method - Web APIs

FileSystemDirectoryHandle: getDirectoryHandle() method
======================================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

 The **`getDirectoryHandle()`** method of the
 `FileSystemDirectoryHandle` interface returns a
 `FileSystemDirectoryHandle` for a subdirectory with the specified name
 within the directory handle on which the method is called.

Syntax
------

```js
getDirectoryHandle(name)
getDirectoryHandle(name, options)
```

### Parameters

`name`

 A string representing the `FileSystemHandle.name` of
 the subdirectory you wish to retrieve.

`options` Optional

 An optional object containing options for the retrieved subdirectory. Options are as
 follows:

`create` Optional

 A boolean value, which defaults to `false`. When
 set to `true` if the directory is not found, one with the specified
 name will be created and returned.

### Return value

A `Promise` which resolves with a `FileSystemDirectoryHandle`.

### Exceptions

`NotAllowedError` `DOMException`

Thrown if the `PermissionStatus.state` for the handle is not `'granted'` in `readwrite` mode if the `create` option is set to `true` or in `read` mode if the `create` option is set to `false`.

`TypeError`

 Thrown if the name specified is not a valid string or contains characters that would
 interfere with the native file system.

`TypeMismatchError` `DOMException`

Thrown if the returned entry is a file and not a directory.

`NotFoundError` `DOMException`

 Thrown if the current entry is not found or if the target directory doesn't exist and the `create` option is set to
 `false`.

Examples
--------

 The following example returns a directory handle with the specified name, if the
 directory does not exist it is created.

```js
const dirName = "directoryToGetName";

// assuming we have a directory handle: 'currentDirHandle'
const subDir = currentDirHandle.getDirectoryHandle(dirName, { create: true });
```

Specifications
--------------

| Specification |
| --- |
| File System Standard # api-filesystemdirectoryhandle-getdirectoryhandle |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* File System API
* The File System Access API: simplifying access to local files


FileSystemDirectoryHandle: entries() method - Web APIs

FileSystemDirectoryHandle: entries() method
===========================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

 The **`entries()`** method of the
 `FileSystemDirectoryHandle` interface returns a new asynchronous iterator
 for the iteration of the key-value pairs of the entries within the `FileSystemDirectoryHandle`
 on which this method is called. The key-value pairs are
 in the form of an array like `[key, value]`.

Syntax
------

```js
entries()
```

### Parameters

None.

### Return value

A new asynchronous iterator containing the key-value pairs of each entry within the `FileSystemDirectoryHandle`.

### Exceptions

`NotAllowedError` `DOMException`

Thrown if the `PermissionStatus.state` for the handle is not `'granted'` in `read` mode.

`NotFoundError` `DOMException`

Thrown if the current entry is not found.

Examples
--------

Use the `for await...of` loop can simplify the iteration process.

```js
const dirHandle = await window.showDirectoryPicker();

for await (const [key, value] of dirHandle.entries()) {
  console.log({ key, value });
}
```

Specifications
--------------

| Specification |
| --- |
| File System Standard # api-filesystemdirectoryhandle-asynciterable |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* File System API
* The File System Access API: simplifying access to local files


FileSystemDirectoryHandle: resolve() method - Web APIs

FileSystemDirectoryHandle: resolve() method
===========================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

 The **`resolve()`** method of the
 `FileSystemDirectoryHandle` interface returns an `Array` of
 directory names from the parent handle to the specified child entry, with the name of
 the child entry as the last array item.

Syntax
------

```js
resolve(possibleDescendant)
```

### Parameters

`possibleDescendant`

The `FileSystemHandle` from which to return the relative path.

### Return value

 A `Promise` which resolves with an `Array` of
 strings, or `null` if `possibleDescendant` is not a descendant of this `FileSystemDirectoryHandle`.

### Exceptions

No exceptions are thrown.

Examples
--------

 The following asynchronous function uses `resolve()` to find the path to a
 chosen file, relative to a specified directory handle.

```js
async function returnPathDirectories(directoryHandle) {
  // Get a file handle by showing a file picker:
  const [handle] = await self.showOpenFilePicker();
  if (!handle) {
    // User cancelled, or otherwise failed to open a file.
    return;
  }

  // Check if handle exists inside our directory handle
  const relativePaths = await directoryHandle.resolve(handle);

  if (relativePaths === null) {
    // Not inside directory handle
  } else {
    // relativePath is an array of names, giving the relative path
    for (const name of relativePaths) {
      // log each entry
      console.log(name);
    }
  }
}
```

Specifications
--------------

| Specification |
| --- |
| File System Standard # api-filesystemdirectoryhandle-resolve |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* File System API
* The File System Access API: simplifying access to local files


FileSystemDirectoryHandle: removeEntry() method - Web APIs

FileSystemDirectoryHandle: removeEntry() method
===============================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

 The **`removeEntry()`** method of the
 `FileSystemDirectoryHandle` interface attempts to remove an entry if the
 directory handle contains a file or directory called the name specified.

Syntax
------

```js
removeEntry(name)
removeEntry(name, options)
```

### Parameters

`name`

 A string representing the `FileSystemHandle.name` of
 the entry you wish to remove.

`options` Optional

An optional object containing options, which are as follows:

`recursive` Optional

A boolean value, which defaults to `false`. When set to `true` entries will be removed recursively.

### Return value

A `Promise` which resolves with `undefined`.

### Exceptions

`TypeError`

Thrown if the name is not a valid string or contains characters not allowed on the file system.

`NotAllowedError` `DOMException`

Thrown if the `PermissionStatus.state` for the handle is not `'granted'` in `readwrite` mode.

`InvalidModificationError` `DOMException`

Thrown if `recursive` is set to false and the entry to be removed has children.

`NotFoundError` `DOMException`

Thrown if the current entry is not found or if the entry of the specific name is not found or matched.

Examples
--------

The following example removes an entry within the directory handle.

```js
const entryName = "entryToRemove";

// assuming we have a directory handle: 'currentDirHandle'
currentDirHandle.removeEntry(entryName).then(() => {
  // code to run if removing was successful
});
```

Specifications
--------------

| Specification |
| --- |
| File System Standard # api-filesystemdirectoryhandle-removeentry |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* File System API
* The File System Access API: simplifying access to local files


FileSystemDirectoryHandle: values() method - Web APIs

FileSystemDirectoryHandle: values() method
==========================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

 The **`values()`** method of the
 `FileSystemDirectoryHandle` interface returns a new asynchronous iterator
 for the iteration of the value of the entries within the `FileSystemDirectoryHandle`
 on which this method is called.

Syntax
------

```js
values()
```

### Parameters

None.

### Return value

A new asynchronous iterator containing the handles of each entry within the `FileSystemDirectoryHandle`.

### Exceptions

`NotAllowedError` `DOMException`

Thrown if the `PermissionStatus.state` for the handle is not `'granted'` in `read` mode.

`NotFoundError` `DOMException`

Thrown if the current entry is not found.

Examples
--------

Use the `for await...of` loop can simplify the iteration process.

```js
const dirHandle = await window.showDirectoryPicker();

for await (const value of dirHandle.values()) {
  console.log(value);
}
```

Specifications
--------------

| Specification |
| --- |
| File System Standard # api-filesystemdirectoryhandle-asynciterable |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* File System API
* The File System Access API: simplifying access to local files


Blob: text() method - Web APIs

Blob: text() method
===================

**Note:** This feature is available in Web Workers

 The **`text()`** method of the
 `Blob` interface returns a `Promise` that resolves with a
 string containing the contents of the blob, interpreted as UTF-8.

Syntax
------

```js
text()
```

### Parameters

None.

### Return value

 A promise that resolves with a string which contains the blob's data
 as a text string. The data is *always* presumed to be in UTF-8 format.

Usage notes
-----------

 The `FileReader` method `readAsText()` is an older method that performs a similar function. It works on both
 `Blob` and `File` objects. There are two key differences:

* `Blob.text()` returns a promise, whereas
 `FileReader.readAsText()` is an event based API.
* `Blob.text()` always uses UTF-8 as encoding, while
 `FileReader.readAsText()` can use a different encoding depending on the
 blob's type and a specified encoding name.
Specifications
--------------

| Specification |
| --- |
| File API # dom-blob-text |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Response.text()`
* Streams API
* `FileReader.readAsText()`


Blob: size property - Web APIs

Blob: size property
===================

**Note:** This feature is available in Web Workers

 The **`size`** read-only property of the `Blob` interface returns
 the size of the `Blob` or `File` in bytes.

Value
-----

 The number of bytes of data contained within the `Blob` (or
 `Blob`-based object, such as a `File`).

Examples
--------

 This example uses an `<input>` element of type `file` to ask
 the user for a group of files, then iterates over those files outputting their names and
 lengths in bytes.

### HTML

```html
<input type="file" id="input" multiple />
<output id="output">Choose files…</output>
```

```
output {
  display: block;
  margin-top: 16px;
}
```

### JavaScript

```js
const input = document.getElementById("input");
const output = document.getElementById("output");

input.addEventListener("change", (event) => {
  output.innerText = "";

  for (const file of event.target.files) {
    output.innerText += `${file.name} has a size of ${file.size} bytes.\n`;
  }
});
```

### Result

Specifications
--------------

| Specification |
| --- |
| File API # dfn-size |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Blob`
* Using files from web applications


Blob: Blob() constructor - Web APIs

Blob: Blob() constructor
========================

**Note:** This feature is available in Web Workers

 The **`Blob()`** constructor returns a
 new `Blob` object. The content of the blob consists of the concatenation
 of the values given in the parameter `array`.

Syntax
------

```js
new Blob(blobParts)
new Blob(blobParts, options)
```

### Parameters

`blobParts` Optional

 An iterable
 object such as an `Array`, having `ArrayBuffer`s,
 `TypedArray`s, `DataView`s, `Blob`s, strings,
 or a mix of any of such elements, that will be put inside the `Blob`.
 Strings should be well-formed Unicode, and lone surrogates are sanitized using the same algorithm as `String.prototype.toWellFormed()`.

`options` Optional

An object which may specify any of the following properties:

`type` Optional

 The MIME type of the data that will be stored into the blob. The
 default value is the empty string, (`""`).

`endings` Optional

 How to interpret newline characters (`\n`) within the contents, if
 the data is text. The default value, `transparent`, copies newline
 characters into the blob without changing them. To convert newlines to the host
 system's native convention, specify the value `native`.

### Return value

A new `Blob` object containing the specified data.

Examples
--------

```js
const array = ['<q id="a"><span id="b">hey!</span></q>']; // an array consisting of a single string
const blob = new Blob(array, { type: "text/html" }); // the blob
```

Specifications
--------------

| Specification |
| --- |
| File API # constructorBlob |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Blob: arrayBuffer() method - Web APIs

Blob: arrayBuffer() method
==========================

**Note:** This feature is available in Web Workers

 The **`arrayBuffer()`** method of the `Blob`
 interface returns a `Promise` that resolves with the contents of the blob as
 binary data contained in an `ArrayBuffer`.

Syntax
------

```js
arrayBuffer()
```

### Parameters

None.

### Return value

 A promise that resolves with an `ArrayBuffer` that contains the blob's
 data in binary form.

### Exceptions

 While this method doesn't throw exceptions, it may reject the promise. This can happen,
 for example, if the reader used to fetch the blob's data throws an exception. Any
 exceptions thrown while getting the data will be converted into rejections.

Usage notes
-----------

 While similar to the `FileReader.readAsArrayBuffer()` method,
 `arrayBuffer()` returns a promise rather than being an event-based API, as is
 the case with the `FileReader` interface's method.

Specifications
--------------

| Specification |
| --- |
| File API # dom-blob-arraybuffer |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Response.arrayBuffer()`
* Streams API
* `FileReader.readAsArrayBuffer()`


Blob: stream() method - Web APIs

Blob: stream() method
=====================

**Note:** This feature is available in Web Workers

The **`stream()`** method of the `Blob` interface returns a `ReadableStream` which upon reading returns the data contained within the `Blob`.

Syntax
------

```js
stream()
```

### Parameters

None.

### Return value

 A `ReadableStream` which, upon reading, returns the contents of the
 `Blob`.

Usage notes
-----------

 With `stream()` and the returned `ReadableStream`, you gain
 several interesting capabilities:

* Call `getReader()` on the returned stream
 to get an object to use to read the data from the blob using methods such as the
 `ReadableStreamDefaultReader` interface's
 `read()` method.
* Call the returned stream's `pipeTo()` method
 to pipe the blob's data to a writable stream.
* Call the returned stream's `tee()` method to
 **tee** the readable stream. This returns an array containing two new
 `ReadableStream` objects, each of which returns the contents of the
 `Blob`.
* Call the returned stream's `pipeThrough()` method to pipe the stream through a `TransformStream`
 or any other readable and writable pair.
Specifications
--------------

| Specification |
| --- |
| File API # dom-blob-stream |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Response.body`
* Streams API


Blob: slice() method - Web APIs

Blob: slice() method
====================

**Note:** This feature is available in Web Workers

 The **`slice()`** method of the `Blob` interface
 creates and returns a new `Blob` object which contains data from a subset of
 the blob on which it's called.

Syntax
------

```js
slice()
slice(start)
slice(start, end)
slice(start, end, contentType)
```

### Parameters

`start` Optional

 An index into the `Blob` indicating the first byte to include in the
 new `Blob`. If you specify a negative value, it's treated as an offset
 from the end of the `Blob` toward the beginning. For example, -10 would
 be the 10th from last byte in the `Blob`. The default value is 0. If you
 specify a value for `start` that is larger than the size of the source
 `Blob`, the returned `Blob` has size 0 and contains no data.

`end` Optional

 An index into the `Blob` indicating the first byte that will *not* be
 included in the new `Blob` (i.e. the byte exactly at this index is not
 included). If you specify a negative value, it's treated as an offset from the end of
 the `Blob` toward the beginning. For example, -10 would be the 10th from
 last byte in the `Blob`. The default value is `size`.

`contentType` Optional

 The content type to assign to the new `Blob`; this will be the value of
 its `type` property. The default value is an empty string.

### Return value

 A new `Blob` object containing the specified subset of the data contained
 within the blob on which this method was called. The original blob is not altered.

Specifications
--------------

| Specification |
| --- |
| File API # dfn-slice |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Blob`
* Using files from web applications


Blob: type property - Web APIs

Blob: type property
===================

**Note:** This feature is available in Web Workers

The **`type`** read-only property of the `Blob` interface returns the MIME type of the file.

**Note:** Based on the current implementation, browsers won't actually read the bytestream of a file to determine its media type.
 It is assumed based on the file extension; a PNG image file renamed to .txt would give "*text/plain*" and not "*image/png*". Moreover, `blob.type` is generally reliable only for common file types like images, HTML documents, audio and video.
 Uncommon file extensions would return an empty string.
 Client configuration (for instance, the Windows Registry) may result in unexpected values even for common types. **Developers are advised not to rely on this property as a sole validation scheme.**

Value
-----

 A string containing the file's MIME type, or an empty string if the
 type could not be determined.

Examples
--------

 This example asks the user to select a number of files, then checks each file to make
 sure it's one of a given set of image file types.

### HTML

```html
<input type="file" id="input" multiple />
<output id="output">Choose image files…</output>
```

```
output {
  display: block;
  margin-top: 16px;
}
```

### JavaScript

```js
// Our application only allows GIF, PNG, and JPEG images
const allowedFileTypes = ["image/png", "image/jpeg", "image/gif"];

const input = document.getElementById("input");
const output = document.getElementById("output");

input.addEventListener("change", (event) => {
  const files = event.target.files;

  if (files.length === 0) {
    output.innerText = "Choose image files…";
    return;
  }

  const allAllowed = Array.from(files).every((file) =>
    allowedFileTypes.includes(file.type),
  );
  output.innerText = allAllowed
    ? "All files clear!"
    : "Please choose image files only.";
});
```

### Result

Specifications
--------------

| Specification |
| --- |
| File API # dfn-type |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Blob`
* Using files from web applications


ContactAddress: country property - Web APIs

ContactAddress: country property
================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`country`** read-only property of the `ContactAddress` interface is a string identifying the address's country using the ISO 3166-1 alpha-2 standard. The string is always in its canonical upper-case form.

Some examples of valid `country` values: `"US"`, `"GB"`, `"CN"`, or `"JP"`.

Value
-----

A string which contains the ISO3166-1 alpha-2 code identifying the country in which the address is located, or an empty string if no country is available, which frequently can be assumed to mean "same country as the site owner."

Specifications
--------------

| Specification |
| --- |
| Contact Picker API # dom-contactaddress-country |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


ContactAddress: organization property - Web APIs

ContactAddress: organization property
=====================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`organization`** read-only property of the `ContactAddress` interface returns a string containing the name of the organization, firm, company, or institution at the address.

Value
-----

A string whose value is the name of the organization or company located at the address described by the `ContactAddress` object.

Specifications
--------------

| Specification |
| --- |
| Contact Picker API # dom-contactaddress-organization |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


ContactAddress: addressLine property - Web APIs

ContactAddress: addressLine property
====================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`addressLine`** read-only property of the `ContactAddress` interface is an array of strings, each specifying a line of the address that is not covered by one of the other properties of `ContactAddress`. The array may include the street name, the house number, apartment number, the rural delivery route, descriptive instructions, or the post office box.

Value
-----

An array of strings, each containing one line of the address. For example, the `addressLine` property for the Mozilla Space in London would have the following entries:

| Index | addressLine[] value |
| --- | --- |
| 0 | Metal Box Factory |
| 1 | Suite 441, 4th floor |
| 2 | 30 Great Guildford Street |

These, combined with additional values for other properties of the `ContactAddress`, would represent the full address, which is:

```plaintext
Mozilla
Metal Box Factory
Suite 441, 4th floor
30 Great Guildford Street
London SE1 0HS
United Kingdom
```

Specifications
--------------

| Specification |
| --- |
| Contact Picker API # dom-contactaddress-addressLine |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


ContactAddress: recipient property - Web APIs

ContactAddress: recipient property
==================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The read-only **`recipient`** property of the `ContactAddress` interface returns a string containing the name of the recipient, purchaser, or contact person at the address.

Value
-----

A string giving the name of the person=, or the name of a contact person in other contexts. If no name is available, this string is empty.

Specifications
--------------

| Specification |
| --- |
| Contact Picker API # dom-contactaddress-recipient |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


ContactAddress: city property - Web APIs

ContactAddress: city property
=============================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`city`** read-only property of the `ContactAddress` interface returns a string containing the city or town portion of the address.

Value
-----

A string indicating the city or town portion of the address described by the `ContactAddress` object.

Specifications
--------------

| Specification |
| --- |
| Contact Picker API # dom-contactaddress-city |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


ContactAddress: toJSON() method - Web APIs

ContactAddress: toJSON() method
===============================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`toJSON()`** method of the `ContactAddress` interface is a standard serializer that returns a JSON representation of the `ContactAddress` object's properties.

Syntax
------

```js
toJSON()
```

### Return value

A JSON object.

Specifications
--------------

| Specification |
| --- |
| Contact Picker API # dom-contactaddress-toJSON |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


ContactAddress: region property - Web APIs

ContactAddress: region property
===============================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The read-only **`region`** property of the `ContactAddress` interface returns a string containing the top-level administrative subdivision of the country in which the address is located. This may be a state, province, oblast, or prefecture.

Value
-----

A string specifying the top-level administrative subdivision within the country in which the address is located. This region has different names in different countries, such as: state, province, oblast, prefecture, or county.

Usage notes
-----------

In some countries, like Belgium, it's uncommon for people to provide a region as part of their postal address. In such cases, the browser returns an empty string as the value of `region`. However, the address should still be acceptable to use for its intended purpose (e.g., to ship a product). However, always verify addresses to make sure what the user provides is usable.

Specifications
--------------

| Specification |
| --- |
| Contact Picker API # dom-contactaddress-region |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


ContactAddress: postalCode property - Web APIs

ContactAddress: postalCode property
===================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`postalCode`** read-only property of the `ContactAddress` interface returns a string containing a code used by a jurisdiction for mail routing, for example, the ZIP Code in the United States or the Postal Index Number (PIN code) in India.

Value
-----

A string which contains the postal code portion of the address. A postal code is a string (either numeric or alphanumeric) which is used by a postal service to optimize mail routing and delivery.

Various countries use different terms for this. In most of the world, it's known as the "post code" or "postal code". In the United States, the ZIP code is used. India uses PIN codes.

Specifications
--------------

| Specification |
| --- |
| Contact Picker API # dom-contactaddress-postalCode |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Universal Postal Union: Universal Post\*Code® Database


ContactAddress: phone property - Web APIs

ContactAddress: phone property
==============================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The read-only **`phone`** property of the `ContactAddress` interface returns a string containing the telephone number of the recipient or contact person at the address.

Value
-----

A string containing the telephone number for the recipient of the shipment. If no phone number is available, this value is an empty string.

Specifications
--------------

| Specification |
| --- |
| Contact Picker API # dom-contactaddress-phone |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


ContactAddress: dependentLocality property - Web APIs

ContactAddress: dependentLocality property
==========================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The read-only **`dependentLocality`** property of the `ContactAddress` interface is a string containing a locality or sublocality designation within a city, such as a neighborhood, borough, district, or, in the United Kingdom, a dependent locality. Also known as a *post town*.

Value
-----

A string indicating the sublocality portion of the address. This may be an empty string if no sublocality is available or required. It's used to provide disambiguation when a city may include areas that duplicate street names.

A sublocality is an area within a city, such as a neighborhood, borough, or district. In the United Kingdom, this is used to indicate the **post town** in the United Kingdom (known officially by the Royal Mail as the **dependent locality**). This is a disambiguating feature of addresses in places where a city may have areas that duplicate street names.

Specifications
--------------

| Specification |
| --- |
| Contact Picker API # dom-contactaddress-dependentLocality |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


ContactAddress: sortingCode property - Web APIs

ContactAddress: sortingCode property
====================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`sortingCode`** read-only property of the `ContactAddress` interface returns a string containing a postal sorting code such as is used in France.

Value
-----

A string containing the sorting code portion of the address.

Specifications
--------------

| Specification |
| --- |
| Contact Picker API # dom-contactaddress-sortingCode |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Clients: get() method - Web APIs

Clients: get() method
=====================

 The **`get()`** method of the
 `Clients` interface gets a service worker client matching a given
 `id` and returns it in a `Promise`.

Syntax
------

```js
get(id)
```

### Parameters

`id`

A string representing the id of the client you want to get.

### Return value

 A `Promise` that resolves to a `Client` object or
 `undefined`.

Examples
--------

```js
self.clients.get(id).then((client) => {
  self.clients.openWindow(client.url);
});
```

Specifications
--------------

| Specification |
| --- |
| Service Workers # clients-get |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Clients: claim() method - Web APIs

Clients: claim() method
=======================

 The **`claim()`** method of the `Clients` interface allows an active service worker to set itself as the `controller` for all clients within its `scope`.
 This triggers a "`controllerchange`" event on `navigator.serviceWorker` in any clients that become controlled by this service worker.

 When a service worker is initially registered, pages won't use it until they next
 load. The `claim()` method causes those pages to be controlled immediately.
 Be aware that this results in your service worker controlling pages that loaded
 regularly over the network, or possibly via a different service worker.

Syntax
------

```js
claim()
```

### Parameters

None.

### Return value

A `Promise` that resolves to `undefined`.

Examples
--------

The following example uses `claim()` inside service worker's "`activate`" event listener so that clients loaded in the same scope do not need to be reloaded before their fetches will go through this service worker.

```js
self.addEventListener("activate", (event) => {
  event.waitUntil(clients.claim());
});
```

Specifications
--------------

| Specification |
| --- |
| Service Workers # clients-claim |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using Service Workers
* The service worker lifecycle
* `self.skipWaiting()` - skip the service worker's waiting phase


Clients: openWindow() method - Web APIs

Clients: openWindow() method
============================

 The **`openWindow()`** method of the `Clients`
 interface creates a new top level browsing context and loads a given URL. If the calling
 script doesn't have permission to show popups, `openWindow()` will throw an
 `InvalidAccessError`.

 In Firefox, the method is allowed to show popups only when called as the result of a
 notification click event.

 In Chrome for Android, the method may instead open the URL in an existing browsing
 context provided by a standalone web app previously added to the user's home screen. As of recently, this also works on
 Chrome for Windows.

Syntax
------

```js
openWindow(url)
```

### Parameters

`url`

 A string representing the URL of the client you want to open in
 the window. Generally this value must be a URL from the same origin as the calling
 script.

### Return value

 A `Promise` that resolves to a `WindowClient` object if the
 URL is from the same origin as the service worker or a null
 value otherwise.

### Exceptions

`InvalidAccessError` `DOMException`

The promise is rejected with this exception if none of the windows in the app's origin have transient activation.

Security requirements
---------------------

* At least one window in the app's origin must have transient activation.
Examples
--------

```js
// Send notification to OS if applicable
if (self.Notification.permission === "granted") {
  const notificationObject = {
    body: "Click here to view your messages.",
    data: { url: `${self.location.origin}/some/path` },
    // data: { url: 'http://example.com' },
  };
  self.registration.showNotification(
    "You've got messages!",
    notificationObject,
  );
}

// Notification click event listener
self.addEventListener("notificationclick", (e) => {
  // Close the notification popout
  e.notification.close();
  // Get all the Window clients
  e.waitUntil(
    clients.matchAll({ type: "window" }).then((clientsArr) => {
      // If a Window tab matching the targeted URL already exists, focus that;
      const hadWindowToFocus = clientsArr.some((windowClient) =>
        windowClient.url === e.notification.data.url
          ? (windowClient.focus(), true)
          : false,
      );
      // Otherwise, open a new tab to the applicable URL and focus it.
      if (!hadWindowToFocus)
        clients
          .openWindow(e.notification.data.url)
          .then((windowClient) => (windowClient ? windowClient.focus() : null));
    }),
  );
});
```

Specifications
--------------

| Specification |
| --- |
| Service Workers # clients-openwindow |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Clients: matchAll() method - Web APIs

Clients: matchAll() method
==========================

 The **`matchAll()`** method of the `Clients`
 interface returns a `Promise` for a list of service worker
 `Client` objects. Include the `options` parameter to return all service worker
 clients whose origin is the same as the associated service worker's origin. If options
 are not included, the method returns only the service worker clients controlled by the
 service worker.

Syntax
------

```js
matchAll()
matchAll(options)
```

### Parameters

`options` Optional

 An options object allowing you to set options for the matching operation. Available
 options are:

`includeUncontrolled`

 A boolean value — if set to
 `true`, the matching operation will return all service worker clients
 who share the same origin as the current service worker. Otherwise, it returns
 only the service worker clients controlled by the current service worker. The
 default is `false`.

`type`

 Sets the type of clients you want matched. Available values
 are `"window"`, `"worker"`, `"sharedworker"`, and
 `"all"`. The default is `"window"`.

### Return value

 A `Promise` that resolves to an array of `Client` objects. In
 Chrome 46/Firefox 54 and later, this method returns clients in most recently focused
 order, correct as per spec.

Examples
--------

```js
clients.matchAll(options).then((clientList) => {
  for (const client of clientList) {
    if (client.url === "index.html") {
      clients.openWindow(client);
      // or do something else involving the matching client
    }
  }
});
```

Specifications
--------------

| Specification |
| --- |
| Service Workers # clients-matchall |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


HID: disconnect event - Web APIs

HID: disconnect event
=====================

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`disconnect`** event of the `HID` interface fires when the user agent disconnects a HID device.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("disconnect", (event) => {});

ondisconnect = (event) => {};
```

Event type
----------

A `HIDConnectionEvent`. Inherits from `Event`.

Event

HIDConnectionEventEvent properties
----------------

*In addition to the properties listed below, properties from the parent interface, `Event`, are available.*

`device` Read only

The `HIDDevice` the event is fired for.

Examples
--------

In the following example an event listener is registered to listen for the disconnection of a device. The name of the device is then printed to the console using `HIDDevice.productName`.

```js
navigator.hid.addEventListener("disconnect", ({ device }) => {
  console.log(`HID disconnected: ${device.productName}`);
});
```

Specifications
--------------

| Specification |
| --- |
| WebHID API # dom-hid-ondisconnect |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


HID: getDevices() method - Web APIs

HID: getDevices() method
========================

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`getDevices()`** method of the `HID` interface gets a list of the connected HID devices that the user has previously been granted access to in response to a `requestDevice()` call.

Syntax
------

```js
getDevices()
```

### Parameters

None.

### Return value

A `Promise` that resolves with a list of `HIDDevice` objects.

Examples
--------

The following example gets a list of devices and logs the device names to the console.

```js
document.addEventListener("DOMContentLoaded", async () => {
  let devices = await navigator.hid.getDevices();
  devices.forEach((device) => {
    console.log(`HID: ${device.productName}`);
  });
});
```

Specifications
--------------

| Specification |
| --- |
| WebHID API # dom-hid-getdevices |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


HID: connect event - Web APIs

HID: connect event
==================

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`connect`** event of the `HID` interface fires when the user agent connects to a HID device.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("connect", (event) => {});

onconnect = (event) => {};
```

Event type
----------

A `HIDConnectionEvent`. Inherits from `Event`.

Event

HIDConnectionEventEvent properties
----------------

*In addition to the properties listed below, properties from the parent interface, `Event`, are available.*

`device` Read only

The `HIDDevice` the event is fired for.

Examples
--------

In the following example an event listener is registered to listen for the connection of a device. The name of the device is then printed to the console using `HIDDevice.productName`.

```js
navigator.hid.addEventListener("connect", ({ device }) => {
  console.log(`HID connected: ${device.productName}`);
});
```

Specifications
--------------

| Specification |
| --- |
| WebHID API # dom-hid-onconnect |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


HID: requestDevice() method - Web APIs

HID: requestDevice() method
===========================

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`requestDevice()`** method of the `HID` interface requests access to a HID device.

The user agent will present a permission dialog including a list of connected devices, and ask the user to select and grant permission to one of these devices.

Syntax
------

```js
requestDevice(options)
```

### Parameters

`options`

An object containing an array of filter objects for possible devices to pair with. Each filter object can have the following properties:

`vendorId` Optional

An integer representing the vendorId of the requested HID device

`productId` Optional

An integer representing the productId of the requested HID device.

`usagePage` Optional

An integer representing the usage page component of the HID usage of the requested device. The usage for a top level collection is used to identify the device type.

Standard HID usage values can be found in the HID Usage Tables document

`usage` Optional

An integer representing the usage ID component of the HID usage of the requested device.

**Note:** The device filters are used to narrow the list of devices presented to the user. If no filters are present, all connected devices are shown. When one or more filters are included, a device is included if any filter matches. To match a filter, all of the rules included in that filter must match.

### Return value

A `Promise` that resolves with an array of connected `HIDDevice` objects that match the filters passed in.

### Exceptions

`SecurityError` `DOMException`

Thrown if the page does not allow access to the HID feature.

Security
--------

Transient user activation is required. The user has to interact with the page or a UI element in order for this feature to work.

Examples
--------

### Matching a device with all four filter rules

In the following example a HID device is requested that has a vendor ID of `0xABCD`, product ID of `0x1234`, usage page `0x0C` and usage ID `0x01`. Only devices that match all of these rules will be shown.

```js
let requestButton = document.getElementById("request-hid-device");
requestButton.addEventListener("click", async () => {
  let device;
  try {
    const devices = await navigator.hid.requestDevice({
      filters: [
        {
          vendorId: 0xabcd,
          productId: 0x1234,
          usagePage: 0x0c,
          usage: 0x01,
        },
      ],
    });
    device = devices[0];
  } catch (error) {
    console.log("An error occurred.");
  }

  if (!device) {
    console.log("No device was selected.");
  } else {
    console.log(`HID: ${device.productName}`);
  }
});
```

### An example with two filters

This next example includes two filters. Devices will be shown if they match either of these filters.

```js
// Filter on devices with the Nintendo Switch Joy-Con USB Vendor/Product IDs.
const filters = [
  {
    vendorId: 0x057e, // Nintendo Co., Ltd
    productId: 0x2006, // Joy-Con Left
  },
  {
    vendorId: 0x057e, // Nintendo Co., Ltd
    productId: 0x2007, // Joy-Con Right
  },
];

// Prompt user to select a Joy-Con device.
const [device] = await navigator.hid.requestDevice({ filters });
```

Specifications
--------------

| Specification |
| --- |
| WebHID API # dom-hid-requestdevice |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


PermissionStatus: state property - Web APIs

PermissionStatus: state property
================================

 The **`state`** read-only property of the
 `PermissionStatus` interface returns the state of a requested permission.
 This property returns one of `'granted'`, `'denied'`, or
 `'prompt'`.

Value
-----

One of the following:

* `'granted'`
* `'denied'`
* `'prompt'`
Examples
--------

```js
navigator.permissions
  .query({ name: "geolocation" })
  .then((permissionStatus) => {
    console.log(`geolocation permission state is ${permissionStatus.state}`);
    permissionStatus.onchange = () => {
      console.log(
        `geolocation permission status has changed to ${permissionStatus.state}`,
      );
    };
  });
```

Specifications
--------------

| Specification |
| --- |
| Permissions # dom-permissionstatus-state |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


PermissionStatus: change event - Web APIs

PermissionStatus: change event
==============================

The **`change`** event of the `PermissionStatus` interface fires whenever the `PermissionStatus.state` property changes.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("change", (event) => {});

onchange = (event) => {};
```

Event type
----------

A generic `Event`.

Example
-------

```js
navigator.permissions
  .query({ name: "geolocation" })
  .then((permissionStatus) => {
    console.log(`geolocation permission state is ${permissionStatus.state}`);
    permissionStatus.onchange = () => {
      console.log(
        `geolocation permission state has changed to ${permissionStatus.state}`,
      );
    };
  });
```

Specifications
--------------

| Specification |
| --- |
| Permissions # dom-permissionstatus-onchange |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


PermissionStatus: name property - Web APIs

PermissionStatus: name property
===============================

The **`name`** read-only property of the `PermissionStatus` interface returns the name of a requested permission.

Value
-----

A read-only value that is identical to the `name` argument passed to `navigator.permissions.query()`.

Examples
--------

```js
function stateChangeListener() {
  console.log(`${this.name} permission status changed to ${this.state}`);
}
function queryAndTrackPermission(permissionName) {
  navigator.permissions
    .query({ name: permissionName })
    .then((permissionStatus) => {
      console.log(
        `${permissionName} permission state is ${permissionStatus.state}`,
      );
      permissionStatus.onchange = stateChangeListener;
    });
}
queryAndTrackPermission("geolocation");
queryAndTrackPermission("midi");
```

Specifications
--------------

| Specification |
| --- |
| Permissions # dom-permissionstatus-name |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


SVGAnimatedEnumeration: baseVal property - Web APIs

SVGAnimatedEnumeration: baseVal property
========================================

The **`baseVal`** property of the `SVGAnimatedEnumeration` interface contains the initial value of an SVG enumeration.

Value
-----

An integer containing the initial value of the enumeration

Examples
--------

Considering this snippet with a `<clipPath>` element: Its `clipPathUnits` is associated with a `SVGAnimatedEnumeration` object.

```html
<svg viewBox="0 0 100 100" width="200" height="200">
  <clipPath id="clip1" clipPathUnits="userSpaceOnUse">
    <circle cx="50" cy="50" r="35" />
  </clipPath>

  <!-- Some reference rect to materialized to clip path -->
  <rect id="r1" x="0" y="0" width="45" height="45" />
</svg>
```

This snippet gets the element, and logs the `baseVal`of the `SVGClipPathElement.clipPathUnits` property.

```js
const clipPathElt = document.getElementById("clip1");
console.log(clipPathElt.clipPathUnits.baseVal); // Logs 1 that correspond to userSpaceOnUse
```

Specifications
--------------

| Specification |
| --- |
| Scalable Vector Graphics (SVG) 2 # \_\_svg\_\_SVGAnimatedEnumeration\_\_baseVal |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `SVGAnimatedEnumeration.animVal`


SVGAnimatedEnumeration: animVal property - Web APIs

SVGAnimatedEnumeration: animVal property
========================================

The **`animVal`** property of the `SVGAnimatedEnumeration` interface contains the current value of an SVG enumeration. If there is no animation, it is the same value as the `baseVal`.

Value
-----

An integer containing the current value of the enumeration

Examples
--------
```

html,
body,
svg {
  height: 100%;
}
```

```html
<div>
  <svg viewBox="0 0 100 100" width="200" height="200">
    <clipPath id="clip1" clipPathUnits="userSpaceOnUse">
      <animate
 attributeName="clipPathUnits"
 values="userSpaceOnUse;objectBoundingBox;userSpaceOnUse"
 dur="2s"
 repeatCount="indefinite" />
      <circle cx="50" cy="50" r="25" />
    </clipPath>

    <rect id="r1" x="0" y="0" width="50" height="100" />

    <use clip-path="url(#clip1)" href="#r1" fill="lightblue" />
  </svg>
</div>
<pre id="log"></pre>
```

```js
const clipPath1 = document.getElementById("clip1");
const log = document.getElementById("log");

function displayLog() {
  const animValue = clipPath1.clipPathUnits.animVal;
  const baseValue = clipPath1.clipPathUnits.baseVal;
  log.textContent = `The 'clipPathUnits.animVal' is ${animValue}.\n`;
  log.textContent += `The 'clipPathUnits.baseVal' is ${baseValue}.`;
  requestAnimationFrame(displayLog);
}

displayLog();
```

Specifications
--------------

| Specification |
| --- |
| Scalable Vector Graphics (SVG) 2 # \_\_svg\_\_SVGAnimatedEnumeration\_\_animVal |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `SVGAnimatedEnumeration.baseVal`


Using the Web Animations API - Web APIs

Using the Web Animations API
============================

The Web Animations API lets us construct animations and control their playback with JavaScript. This article will start you off in the right direction with fun demos and tutorials featuring Alice in Wonderland.

Meet the Web Animations API
---------------------------

The Web Animations API opens the browser's animation engine to developers and manipulation by JavaScript. This API was designed to underlie implementations of both CSS Animations and CSS Transitions, and leaves the door open to future animation effects. It is one of the most performant ways to animate on the Web, letting the browser make its own internal optimizations without hacks, coercion, or `Window.requestAnimationFrame()`.

With the Web Animations API, we can move interactive animations from stylesheets to JavaScript, separating presentation from behavior. We no longer need to rely on DOM-heavy techniques such as writing CSS properties and scoping classes onto elements to control playback direction. And unlike pure, declarative CSS, JavaScript also lets us dynamically set values from properties to durations. For building custom animation libraries and creating interactive animations, the Web Animations API might be the perfect tool for the job. Let's see what it can do!

Writing CSS Animations with the Web Animations API
--------------------------------------------------

One of the more familiar ways to approach learning the Web Animations API is to start with something most web developers have played with before: CSS Animations. CSS Animations have a familiar syntax that breaks down nicely for demonstration purposes.

### The CSS version

Here's a tumbling animation written in CSS showing Alice falling down the rabbit hole that leads to Wonderland (see the full code on Codepen):

![Alice Tumbling down the rabbit's hole.](/en-US/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API/tumbling-alice_optimized.gif)

Notice that the background moves, Alice spins, and her color changes at an offset from her spinning. We're going to focus on just Alice for this tutorial. Here's the simplified CSS that controls Alice's animation:

```css
#alice {
  animation: aliceTumbling infinite 3s linear;
}

@keyframes aliceTumbling {
  0% {
    color: #000;
    transform: rotate(0) translate3D(-50%, -50%, 0);
  }
  30% {
    color: #431236;
  }
  100% {
    color: #000;
    transform: rotate(360deg) translate3D(-50%, -50%, 0);
  }
}
```

This changes Alice's color and her transform's rotation over 3 seconds at a constant (linear) rate and loops infinitely. In the @keyframes block we can see that 30% of the way through each loop (about .9 seconds in), Alice's color changes from black to a deep burgundy then back again by the end of the loop.

### Moving it to JavaScript

Now let's try creating the same animation with the Web Animations API.

#### Representing keyframes

The first thing we need is to create a Keyframe Object corresponding to our CSS @keyframes block:

```js
const aliceTumbling = [
  { transform: "rotate(0) translate3D(-50%, -50%, 0)", color: "#000" },
  { color: "#431236", offset: 0.3 },
  { transform: "rotate(360deg) translate3D(-50%, -50%, 0)", color: "#000" },
];
```

Here we're using an array containing multiple objects. Each object represents a key from the original CSS. However, unlike CSS, the Web Animations API doesn't need to explicitly be told the percentages along the animation for each key to appear at. It will automatically divide the animation into equal parts based on the number of keys you give it. This means that a Keyframe object with three keys will play the middle key 50% of the way through each loop of the animation unless told otherwise.

When we want to explicitly set a key's offset from the other keys, we can specify an offset directly in the object, separated from the declaration with a comma. In the above example, to make sure that Alice's color changes at 30% (not 50%) for the color change, we are giving it `offset: 0.3`.

Currently, there should be at least two keyframes specified (representing the starting and ending states of the animation sequence). If your keyframe list has only one entry, `Element.animate()` may throw a `NotSupportedError` `DOMException` in some browsers until they are updated.

So to recap, the keys are equally spaced by default unless you specify an offset on a key. Handy, no?

#### Representing timing properties

We'll also need to create an object of timing properties corresponding to the values in Alice's animation:

```js
const aliceTiming = {
  duration: 3000,
  iterations: Infinity,
};
```

You'll notice a few differences here from how equivalent values are represented in CSS:

* For one, the duration is in milliseconds as opposed to seconds — 3000 not 3s. Like `setTimeout()` and `Window.requestAnimationFrame()`, the Web Animations API only takes milliseconds.
* The other thing you'll notice is that it's `iterations`, not `iteration-count`.

**Note:** There are a number of small differences between the terminology used in CSS Animations and the terminology used in Web Animations. For instance, Web Animations doesn't use the string `"infinite"`, but instead uses the JavaScript keyword `Infinity`. And instead of `timing-function` we use `easing`. We aren't listing an `easing` value here because, unlike CSS Animations where the default animation-timing-function is `ease`, in the Web Animations API the default easing is `linear` — which is what we want here.

#### Bring the pieces together

Now it's time to bring them both together with the `Element.animate()` method:

```js
document.getElementById("alice").animate(aliceTumbling, aliceTiming);
```

And boom: the animation starts playing (see the finished version on Codepen).

The `animate()` method can be called on any DOM element that could be animated with CSS. And it can be written in several ways. Instead of making objects for keyframes and timing properties, we could just pass their values in directly, like so:

```js
document.getElementById("alice").animate(
  [
    { transform: "rotate(0) translate3D(-50%, -50%, 0)", color: "#000" },
    { color: "#431236", offset: 0.3 },
    { transform: "rotate(360deg) translate3D(-50%, -50%, 0)", color: "#000" },
  ],
  {
    duration: 3000,
    iterations: Infinity,
  },
);
```

What's more, if we only wanted to specify the duration of the animation and not its iterations (by default, animations iterate once), we could pass in the milliseconds alone:

```js
document.getElementById("alice").animate(
  [
    { transform: "rotate(0) translate3D(-50%, -50%, 0)", color: "#000" },
    { color: "#431236", offset: 0.3 },
    { transform: "rotate(360deg) translate3D(-50%, -50%, 0)", color: "#000" },
  ],
  3000,
);
```

Controlling playback with play(), pause(), reverse(), and updatePlaybackRate()
------------------------------------------------------------------------------

While we can write CSS Animations with the Web Animations API, where the API really comes in handy is manipulating the animation's playback. The Web Animations API provides several useful methods for controlling playback. Let's take a look at pausing and playing animations in the Growing/Shrinking Alice game (check out the full code on Codepen):

![Playing the growing and shrinking game with Alice.](/en-US/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API/growing-shrinking_article_optimized.gif)

In this game, Alice has an animation that causes her to go from small to big which we control via a bottle and a cupcake. Both of these have their own animations.

### Pausing and playing animations

We'll talk more about Alice's animation later, but for now, let's look closer at the cupcake's animation:

```js
const nommingCake = document
  .getElementById("eat-me\_sprite")
  .animate(
    [{ transform: "translateY(0)" }, { transform: "translateY(-80%)" }],
    {
      fill: "forwards",
      easing: "steps(4, end)",
      duration: aliceChange.effect.getComputedTiming().duration / 2,
    },
  );
```

The `Element.animate()` method will immediately run after it is called. To prevent the cake from eating itself up before the user has had the chance to click on it, we call `Animation.pause()` on it immediately after it is defined, like so:

```js
nommingCake.pause();
```

We can now use the `Animation.play()` method to run it whenever we're ready:

```js
nommingCake.play();
```

Specifically, we want to link it to Alice's animation, so she gets bigger as the cupcake gets eaten. We can achieve this via the following function:

```js
const growAlice = () => {
  // Play Alice's animation.
  aliceChange.play();

  // Play the cake's animation.
  nommingCake.play();
};
```

When a user holds their mouse down or presses their finger on the cake on a touch screen, we can now call `growAlice` to make all the animations play:

```js
cake.addEventListener("mousedown", growAlice, false);
cake.addEventListener("touchstart", growAlice, false);
```

### Other useful methods

In addition to pausing and playing, we can use the following Animation methods:

* `Animation.finish()` skips to the end of the animation.
* `Animation.cancel()` aborts the animation and removes its effects.
* `Animation.reverse()` sets the animation's playback rate (`Animation.playbackRate`) to a negative value so it runs backward.

Let's take a look at `playbackRate` first — a negative playbackRate will cause an animation to run in reverse. When Alice drinks from the bottle, she grows smaller. This is because the bottle changes her animation's playbackRate from 1 to -1:

```js
const shrinkAlice = () => {
  aliceChange.playbackRate = -1;
  aliceChange.play();
};

bottle.addEventListener("mousedown", shrinkAlice, false);
bottle.addEventListener("touchstart", shrinkAlice, false);
```

In Through the Looking-Glass, Alice travels to a world where she must run to stay in place — and run twice as fast to move forward! In the Red Queen's Race example, Alice and the Red Queen are running to stay in place (check out the full code on Codepen):

![Alice and the Red Queen race to get to the next square in this game.](/en-US/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API/red-queen-race_optimized.gif)

Because small children tire out easily, unlike automaton chess pieces, Alice is constantly slowing down. We can do this by setting a decay on her animation's `playbackRate`. We use `updatePlaybackRate()` instead of setting the playbackRate directly since that produces a smooth update:

```js
setInterval(() => {
  // Make sure the playback rate never falls below .4
  if (redQueen_alice.playbackRate > 0.4) {
    redQueen_alice.updatePlaybackRate(redQueen_alice.playbackRate \* 0.9);
  }
}, 3000);
```

But urging them on by clicking or tapping causes them to speed up by multiplying their playbackRate:

```js
const goFaster = () => {
  redQueen_alice.updatePlaybackRate(redQueen_alice.playbackRate \* 1.1);
};

document.addEventListener("click", goFaster);
document.addEventListener("touchstart", goFaster);
```

The background elements also have `playbackRate`s that are impacted when you click or tap. What happens when you make Alice and the Red Queen run twice as fast? What happens when you let them slow down?

Persisting animation styles
---------------------------

When animating elements, a common use case is to persist the final state of the animation, after the animation has finished. One method sometimes used for this is to set the animation's fill mode to `forwards`. However, it is not recommended to use fill modes to persist the effect of an animation indefinitely, for two reasons:

* The browser has to maintain the state of the animation while it is still active, so the animation continues to consume resources even though it is no longer animating. Note that this is somewhat alleviated by the browser automatically removing filling animations.
* Styles applied by animations have a higher precedence in the cascade than specified styles, so it can be difficult to override them when needed.

A better approach is to use the `Animation.commitStyles()` method. This writes the computed values of the animation's current styles into its target element's `style` attribute, after which the element can be restyled normally.

Automatically removing filling animations
-----------------------------------------

It is possible to trigger a large number of animations on the same element. If they are indefinite (i.e., forwards-filling), this can result in a huge animations list, which could create a memory leak. For this reason, browsers automatically remove filling animations after they are replaced by newer animations, unless the developer explicitly specifies to keep them.

Animations are removed when all of the following are true:

* The animation is filling (its `fill` is `forwards` if it is playing forwards, `backwards` if it is playing backwards, or `both`).
* The animation is finished. (Note that because of the `fill` it will still be in effect.)
* The animation's timeline is monotonically increasing. (This is always true for `DocumentTimeline`; other timelines such as `scroll-timeline` can run backwards.)
* The animation is not being controlled by declarative markup such as CSS.
* Every styling effect of the animation's `AnimationEffect` is being overridden by another animation that also satisfies all the conditions above. (Typically, when two animations would set the same style property of the same element, the one created last overrides the other.)

The first four conditions ensure that, without intervention by JavaScript code, the animation's effect will never change or end. The last condition ensures that the animation will never actually affect the style of any element: it has been entirely replaced.

When the animation is automatically removed, the animation's `remove` event fires.

To prevent the browser from automatically removing animations, call the animation's `persist()` method.

The animation's `animation.replaceState` property will be `removed` if the animation has been removed, `persisted` if you have called `persist()` on the animation, or `active` otherwise.

Getting information out of animations
-------------------------------------

Imagine other ways we could use playbackRate, such as improving accessibility for users with vestibular disorders by letting them slow down animations across an entire site. That's impossible to do with CSS without recalculating durations in every CSS rule, but with the Web Animations API, we could use the `Document.getAnimations` method to loop over each animation on the page and halve their `playbackRate`s, like so:

```js
document.getAnimations().forEach((animation) => {
  animation.updatePlaybackRate(animation.playbackRate \* 0.5);
});
```

With the Web Animations API, all you need to change is just one little property!

Another thing that's tough to do with CSS Animations alone is creating dependencies on values provided by other animations. For instance, in the Growing and Shrinking Alice game example, you might have noticed something odd about the cake's duration:

```js
document.getElementById("eat-me\_sprite").animate([], {
  duration: aliceChange.effect.timing.duration / 2,
});
```

To understand what's happening here, let's take a look at Alice's animation:

```js
const aliceChange = document
  .getElementById("alice")
  .animate(
    [
      { transform: "translate(-50%, -50%) scale(.5)" },
      { transform: "translate(-50%, -50%) scale(2)" },
    ],
    {
      duration: 8000,
      easing: "ease-in-out",
      fill: "both",
    },
  );
```

Alice's animation has her going from half her size to twice her size over 8 seconds. Then we pause her:

```js
aliceChange.pause();
```

If we had left her paused at the beginning of her animation, she'd start at half her full size, as if she'd drunk the entire bottle already! We want to set her animation's "playhead" in the middle, so she's already halfway done. We could do that by setting her `Animation.currentTime` to 4 seconds, like so:

```js
aliceChange.currentTime = 4000;
```

But while working on this animation, we might change Alice's duration a lot. Wouldn't it be better if we set her `currentTime` dynamically, so we don't have to make two updates at a time? We can, in fact, do so by referencing aliceChange's `Animation.effect` property, which returns an object containing all the details of the effect(s) active on Alice:

```js
aliceChange.currentTime = aliceChange.effect.getComputedTiming().duration / 2;
```

`effect` lets us access the animation's keyframes and timing properties — `aliceChange.effect.getComputedTiming()` points to Alice's timing object — this contains her `duration`. We can divide her duration in half to get the midpoint for her animation's timeline, setting her to be normal height. Now we can reverse and play her animation in either direction to make her grow smaller or larger!

And we can do the same thing when setting the cake and bottle durations:

```js
const drinking = document
  .getElementById("liquid")
  .animate([{ height: "100%" }, { height: "0" }], {
    fill: "forwards",
    duration: aliceChange.effect.getComputedTiming().duration / 2,
  });
drinking.pause();
```

Now all three animations are linked to just one duration, which we can change easily from one place.

We can also use the Web Animations API to figure out the animation's current time. The game ends when you run out of cake to eat or empty the bottle. Which vignette players are presented with depends on how far along Alice was in her animation, whether she grew too big and can't get in the tiny door anymore or too small and cannot reach the key to open the door. We can figure out whether she's on the large end or small end of her animation by getting her animation's `currentTime` and dividing it by her `activeDuration`:

```js
const endGame = () => {
  // get Alice's timeline's playhead location
  const alicePlayhead = aliceChange.currentTime;
  const aliceTimeline = aliceChange.effect.getComputedTiming().activeDuration;

  // stops Alice's and other animations
  stopPlayingAlice();

  // depending on which third it falls into
  const aliceHeight = alicePlayhead / aliceTimeline;

  if (aliceHeight <= 0.333) {
    // Alice got smaller!
    // …
  } else if (aliceHeight >= 0.666) {
    // Alice got bigger!
    // …
  } else {
    // Alice didn't change significantly
    // …
  }
};
```

**Note:** `getAnimations()` and `effect` are not shipping in all browsers as of this writing, but the polyfill does support them today.

Callbacks and promises
----------------------

CSS Animations and Transitions have their own event listeners, and these are also possible with the Web Animations API:

* `onfinish` is the event handler for the `finish` event and can be triggered manually with `finish()`.
* `oncancel` is the event handler for the `cancel` event and can be triggers with `cancel()`.

Here we set the callbacks for the cake, bottle, and Alice to fire the `endGame` function:

```js
// When the cake or bottle runs out
nommingCake.onfinish = endGame;
drinking.onfinish = endGame;

// Alice reaches the end of her animation
aliceChange.onfinish = endGame;
```

Better still, the Web Animations API also provides a `finished` promise that will resolve when the animation finishes, or reject if it is canceled.

Conclusion
----------

These are the basic features of the Web Animations API. By now you should be ready to "jump down the rabbit hole" of animating in the browser and ready to write your own animation experiments!

See also
--------

* The full suite of Alice in Wonderland demos on CodePen for you to play with, fork, and share.
* Animating like you just don't care with Element.animate (2016) Explains the background of the Web Animations API and why it is more performant than other web animation methods.


Web Animations API Concepts - Web APIs

Web Animations API Concepts
===========================

The Web Animations API (WAAPI) provides JavaScript developers access to the browser's animation engine and describes how animations should be implemented across browsers. This article will introduce you to the important concepts behind the WAAPI, providing you with a theoretical understanding of how it works so you can use it effectively. To learn how to put the API to use, check out its sister article, Using the Web Animations API.

The Web Animations API fills the gap between declarative CSS animations and transitions, and dynamic JavaScript animations. This means we can use it to create and manipulate CSS-like animations that go from one pre-defined state to another, or we can use variables, loops, and callbacks to create interactive animations that adapt and react to changing inputs.

History
-------

Over a decade ago, Synchronized Multimedia Integration Language, or SMIL (pronounced "smile"), brought animation to SVG. Back then it was the only animation engine browsers had to worry about. While four out of five browsers supported SMIL, it only animated SVG elements, could not be used from CSS, and was very complex — often leading to inconsistent implementations. Ten years later, the Safari team introduced the CSS Animations and CSS Transitions specs.

The Internet Explorer team requested an animations API to consolidate and normalize animation functionality across all browsers, and thus efforts began in earnest among Mozilla Firefox and Google Chrome developers to create the one animation spec to rule them all: the Web Animations API. Now we've got the WAAPI for future animation specifications to piggyback on, allowing them to remain consistent and play well together. It also provides a point of reference all browsers can adhere to with the currently available specs.

![An illustration showing the Web Animations API ruling over CSS Transitions and Animations as well as a third category representing future animation specs with a question mark.](/en-US/docs/Web/API/Web_Animations_API/Web_Animations_API_Concepts/waapi_diagram_white.png)

The Two Models: Timing and Animation
------------------------------------

The Web Animations API runs on top of two models, one that handles time—Timing—and one that handles visual change over time—Animation. The Timing Model keeps track of how far along a set timeline we've come. The Animation Model determines what the animated object should look like at any given time.

### Timing

The Timing Model is the backbone of working with the WAAPI. Each document has a master timeline, `Document.timeline`, which stretches from the moment the page is loaded to infinity — or until the window is closed. Spread along that timeline according to their durations are our animations. Each animation is anchored to a point in the timeline by its `startTime`, representing the moment along the document's timeline when the animation starts playing.

All the animation's playback relies on this timeline: seeking the animation moves the animation's position along the timeline; slowing down or speeding up the playback rate condenses or expands its spread across the timeline; repeating the animation lines up additional iterations of it along the timeline. In the future, we might have timelines based on gestures or scroll position or even parent and child timelines. The Web Animations API opens up so many possibilities!

### Animation

The animation model can be thought of as an array of snapshots of what the animation could look like at any given time, lined up along the duration of the animation.

![An illustration showing how the animation model can be visualized as a series of snapshots arranged along a timeline. In this case, pictures of the cheshire cat going from 0 (there) to 8 seconds (not all there—only his smile is left).](/en-US/docs/Web/API/Web_Animations_API/Web_Animations_API_Concepts/waapi_timing_diagram_white.png)

Core Concepts
-------------

Web animations consist of Timeline Objects, Animation Objects, and Animation Effect Objects working together. By assembling these disparate objects, we can create animations of our own.

### Timeline

Timeline objects provide the useful property `currentTime`, which lets us see how long the page has been opened for: it's the "current time" of the document's timeline, which started when the page was opened. As of this writing, there's only one kind of timeline object: the one based on the active document's `timeline`. In the future we may see timeline objects that correspond to the length of the page, perhaps a `ScrollTimeline`, or other things entirely.

### Animation

Animation objects can be imagined as DVD players: they're used for controlling media playback, but without media to play, they don't do anything. Animation objects accept media in the form of Animation Effects, specifically Keyframe Effects (we'll get to those in a moment). Like a DVD player, we can use the Animation Object's methods to play, pause, seek, and control the animation's playback direction and speed.

![An illustration likening how an Animation plays a KeyframeEffect like a DVD player plays a DVD.](/en-US/docs/Web/API/Web_Animations_API/Web_Animations_API_Concepts/waapi_player_diagram_white.png)

### Animation Effect

If Animation objects are DVD players, we can think of Animation Effects, or Keyframe Effects, as DVDs. Keyframe Effects are a bundle of information including at the bare minimum a set of keys and the duration they need to be animated over. The Animation Object takes this information and, using the Timeline Object, assembles a playable animation we can view and reference.

We currently have only one animation effect type available: `KeyframeEffect`. Potentially we could have all kinds of Animation Effects in the future—e.g. effects for grouping and sequencing, not unlike features we had in Flash. In fact, Group Effects and Sequence Effects have already been outlined in the currently-in-progress level 2 spec of the Web Animations API.

### Assembling the Animation from disparate pieces

We can assemble all these pieces together to create a working animation with the `Animation()` Constructor or we can use the `Element.animate()` shortcut function. (Read more about how to use `Element.animate()` in Using the Web Animations API.)

Uses
----

The API allows for the creation of dynamic animations that can be updated on the fly as well as more straightforward, declarative animations like those CSS creates. It can be used in automated tests to ensure that your UI animations are running correctly. It opens up the browser's rendering engine for building animation development tools like timelines. It is also a performant base on which to build a custom or commercial animation library. (See Animating like you just don't care with Element.animate.) In some instances, it may negate the need for a fully fledged library entirely in the same way Vanilla JavaScript can be used without jQuery for many purposes.

See also
--------

* Web Animations API — main page
* Using the Web Animations API — guide
* The full suite of Alice in Wonderland demos on CodePen for you to play with, fork, and share
* web-animations-js — the Web Animations API polyfill


Keyframe Formats - Web APIs

Keyframe Formats
================

`Element.animate()`, `KeyframeEffect()`, and `KeyframeEffect.setKeyframes()` all accept objects formatted to represent a set of keyframes. There are several options to this format, which are explained below.

Syntax
------

There are two different ways to format keyframes:

1. An `array` of objects (keyframes) consisting of properties and values to iterate over. This is the canonical format returned by the `getKeyframes()` method.

```js
element.animate(
  [
    {
      // from
      opacity: 0,
      color: "#fff",
    },
    {
      // to
      opacity: 1,
      color: "#000",
    },
  ],
  2000,
);
```

Offsets for each keyframe can be specified by providing an `offset` value.

```js
element.animate(
  [{ opacity: 1 }, { opacity: 0.1, offset: 0.7 }, { opacity: 0 }],
  2000,
);
```

**Note:** `offset` values, if provided, must be between 0.0 and 1.0 (inclusive) and arranged in ascending order.

It is not necessary to specify an offset for every keyframe. Keyframes without a specified offset will be evenly spaced between adjacent keyframes.
 The easing to apply between keyframes can be specified by providing an `easing` value as illustrated below.

```js
element.animate(
  [
    { opacity: 1, easing: "ease-out" },
    { opacity: 0.1, easing: "ease-in" },
    { opacity: 0 },
  ],
  2000,
);
```

In this example, the specified easing only applies from the keyframe where it is specified until the next keyframe. Any `easing` value specified on the `options` argument, however, applies across a single iteration of the animation — for the entire duration.
2. An `object` containing key-value pairs consisting of the property to animate and an `array` of values to iterate over.

```js
element.animate(
  {
    opacity: [0, 1], // [ from, to ]
    color: ["#fff", "#000"], // [ from, to ]
  },
  2000,
);
```

Using this format, the number of elements in each array does not need to be equal. The provided values will be spaced out independently.

```js
element.animate(
  {
    opacity: [0, 1], // offset: 0, 1
    backgroundColor: ["red", "yellow", "green"], // offset: 0, 0.5, 1
  },
  2000,
);
```

The special keys `offset`, `easing`, and `composite` (described below) may be specified alongside the property values.

```js
element.animate(
  {
    opacity: [0, 0.9, 1],
    offset: [0, 0.8], // Shorthand for [ 0, 0.8, 1 ]
    easing: ["ease-in", "ease-out"],
  },
  2000,
);
```

After generating a suitable set of keyframes from the property value lists, each supplied offset is applied to the corresponding keyframe. If there are insufficient values, or if the list contains `null` values, the keyframes without specified offsets will be evenly spaced as with the array format described above.
 If there are too few `easing` or `composite` values, the corresponding list will be repeated as needed.
### Implicit to/from keyframes

In newer browser versions, you are able to set a beginning or end state for an animation only (i.e. a single keyframe), and the browser will infer the other end of the animation if it is able to. For example, consider this simple animation — the Keyframe object looks like so:

```js
let rotate360 = [{ transform: "rotate(360deg)" }];
```

We have only specified the end state of the animation, and the beginning state is implied.

Attributes
----------

Keyframes may specify property-value pairs for any of the `animatable CSS properties`. The property names are specified using camel case so for example `background-color` becomes `backgroundColor` and `background-position-x` becomes `backgroundPositionX`. Shorthand values such as `margin` are also permitted.

Two exceptional CSS properties are:

* `float`, which must be written as `cssFloat` since "float" is a reserved word in JavaScript. It's just for reference here, this will have no effect on animation since "float" is not an animatable CSS property.
* `offset`, which must be written as `cssOffset` since "offset" represents the keyframe offset as described below.

The following special attributes may also be specified:

offset

The offset of the keyframe specified as a number between `0.0` and `1.0` inclusive or `null`. This is equivalent to specifying start and end states in percentages in CSS stylesheets using `@keyframes`. If this value is `null` or missing, the keyframe will be evenly spaced between adjacent keyframes.

easing

The easing function used from this keyframe until the next keyframe in the series.

composite

The `KeyframeEffect.composite` operation used to combine the values specified in this keyframe with the underlying value. This will be `auto` if the composite operation specified on the effect is being used.

See also
--------

* Web Animations API
* `Element.animate()`
* `KeyframeEffect()`
* `KeyframeEffect.setKeyframes()`