HTMLElement: innerText property - Web APIs

HTMLElement: innerText property
===============================

The **`innerText`** property of the `HTMLElement` interface represents the rendered text content of a node and its descendants.

 As a getter, it approximates the text the user would get if they highlighted the contents of the element with the cursor and then copied it to the clipboard.
 As a setter this will replace the element's children with the given value, converting any line breaks into `<br>` elements.

**Note:** `innerText` is easily confused with `Node.textContent`, but there are important differences between the two.
 Basically, `innerText` is aware of the rendered appearance of text, while `textContent` is not.

Value
-----

A string representing the rendered text content of an element.

If the element itself is not being rendered (for example, is detached from the document or is hidden from view), the returned value is the same as the `Node.textContent` property.

**Warning:** Setting `innerText` on a node removes *all* of the node's children
 and replaces them with a single text node with the given string value.

Examples
--------

 This example compares `innerText` with `Node.textContent`.
 Note how `innerText` is aware of things like `<br>` elements, and ignores hidden elements.

### HTML

```html
<h3>Source element:</h3>
<p id="source">
  <style>
 #source {
 color: red;
 }
 #text {
 text-transform: uppercase;
 }
 </style>
  <span id="text">
    Take a look at<br />
    how this text<br />
    is interpreted below.
  </span>
  <span style="display:none">HIDDEN TEXT</span>
</p>
<h3>Result of textContent:</h3>
<textarea id="textContentOutput" rows="6" cols="30" readonly>…</textarea>
<h3>Result of innerText:</h3>
<textarea id="innerTextOutput" rows="6" cols="30" readonly>…</textarea>
```

### JavaScript

```js
const source = document.getElementById("source");
const textContentOutput = document.getElementById("textContentOutput");
const innerTextOutput = document.getElementById("innerTextOutput");

textContentOutput.value = source.textContent;
innerTextOutput.value = source.innerText;
```

### Result

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

| Specification |
| --- |
| HTML Standard # the-innertext-idl-attribute |

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

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

See also
--------

* `HTMLElement.outerText`
* `Element.innerHTML`


HTMLElement: lang property - Web APIs

HTMLElement: lang property
==========================

 The **`HTMLElement.lang`** property gets or sets the base
 language of an element's attribute values and text content.

 The language code returned by this property is defined in RFC 5646: Tags for Identifying Languages (also known as BCP 47).
 Common examples include "en" for English, "ja" for
 Japanese, "es" for Spanish and so on. The default value of this attribute is
 `unknown`. Note that this attribute, though valid at the individual element
 level described here, is most often specified for the root element of the document.

 This also only works with the `lang` attribute and not with
 `xml:lang`.

Value
-----

A string.

Examples
--------

```js
// this snippet compares the base language and
// redirects to another URL based on language
if (document.documentElement.lang === "en") {
  window.location.href = "Some\_document.html.en";
} else if (document.documentElement.lang === "ru") {
  window.location.href = "Some\_document.html.ru";
}
```

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

| Specification |
| --- |
| HTML Standard # dom-lang |

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

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


XREquirectLayer: upperVerticalAngle property - Web APIs

XREquirectLayer: upperVerticalAngle property
============================================

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

The **`upperVerticalAngle`** property of the `XREquirectLayer` interface represents the upper vertical angle in radians for the sphere.

Value
-----

A number representing the upper vertical angle in radians for the sphere. Setting `upperVerticalAngle` to a value less than -π/2 will set it to -π/2 and setting it to a value higher than π/2 will set it to π/2.

Examples
--------

### Getting a layer's upper vertical angle

The `XRWebGLBinding.createEquirectLayer()` method creates an equirect layer and allows specifying a `upperVerticalAngle`. The `XREquirectLayer.upperVerticalAngle` property can be used after layer creation to get the upper vertical angle used or to set it to a new one.

```js
const equirectLayer = xrGlBinding.createEquirectLayer({
  space: xrReferenceSpace,
  viewPixelWidth: 1200,
  viewPixelHeight: 600,
  centralHorizontalAngle: 2 \* Math.PI,
  upperVerticalAngle: Math.PI / 2.0,
  lowerVerticalAngle: -Math.PI / 2.0,
  radius: 0,
});

equirectLayer.upperVerticalAngle; // 1.5707963267948966
```

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

| Specification |
| --- |
| WebXR Layers API Level 1 # dom-xrequirectlayer-upperverticalangle |

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

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

See also
--------

* `XREquirectLayer.radius`
* `XREquirectLayer.centralHorizontalAngle`
* `XREquirectLayer.lowerVerticalAngle`


XREquirectLayer: centralHorizontalAngle property - Web APIs

XREquirectLayer: centralHorizontalAngle property
================================================

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

The **`centralHorizontalAngle`** property of the `XREquirectLayer` interface represents the central horizontal angle in radians for the sphere.

Value
-----

A number representing the central horizontal angle in radians for the sphere. Setting `centralHorizontalAngle` to a value less than 0 will set it to 0 and setting it to a value higher than 2π will set it to 2π.

Examples
--------

### Getting a layer's central horizontal angle

The `XRWebGLBinding.createEquirectLayer()` method creates an equirect layer and allows specifying a `centralHorizontalAngle`. The `XREquirectLayer.centralHorizontalAngle` property can be used after layer creation to get the central horizontal angle used or to set it to a new one.

```js
const equirectLayer = xrGlBinding.createEquirectLayer({
  space: xrReferenceSpace,
  viewPixelWidth: 1200,
  viewPixelHeight: 600,
  centralHorizontalAngle: 2 \* Math.PI,
  upperVerticalAngle: Math.PI / 2.0,
  lowerVerticalAngle: -Math.PI / 2.0,
  radius: 0,
});

equirectLayer.centralHorizontalAngle; // 6.283185307179586
```

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

| Specification |
| --- |
| WebXR Layers API Level 1 # dom-xrequirectlayer-centralhorizontalangle |

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

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

See also
--------

* `XREquirectLayer.radius`
* `XREquirectLayer.lowerVerticalAngle`
* `XREquirectLayer.upperVerticalAngle`


XREquirectLayer: lowerVerticalAngle property - Web APIs

XREquirectLayer: lowerVerticalAngle property
============================================

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

The **`lowerVerticalAngle`** property of the `XREquirectLayer` interface represents the lower vertical angle in radians for the sphere.

Value
-----

A number representing the lower vertical angle in radians for the sphere. Setting `lowerVerticalAngle` to a value less than -π/2 will set it to -π/2 and setting it to a value higher than π/2 will set it to π/2.

Examples
--------

### Getting a layer's lower vertical angle

The `XRWebGLBinding.createEquirectLayer()` method creates an equirect layer and allows specifying a `lowerVerticalAngle`. The `XREquirectLayer.lowerVerticalAngle` property can be used after layer creation to get the lower vertical angle used or to set it to a new one.

```js
const equirectLayer = xrGlBinding.createEquirectLayer({
  space: xrReferenceSpace,
  viewPixelWidth: 1200,
  viewPixelHeight: 600,
  centralHorizontalAngle: 2 \* Math.PI,
  upperVerticalAngle: Math.PI / 2.0,
  lowerVerticalAngle: -Math.PI / 2.0,
  radius: 0,
});

equirectLayer.lowerVerticalAngle; // -1.5707963267948966
```

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

| Specification |
| --- |
| WebXR Layers API Level 1 # dom-xrequirectlayer-lowerverticalangle |

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

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

See also
--------

* `XREquirectLayer.radius`
* `XREquirectLayer.centralHorizontalAngle`
* `XREquirectLayer.upperVerticalAngle`


XREquirectLayer: transform property - Web APIs

XREquirectLayer: transform property
===================================

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

The **`transform`** property of the `XREquirectLayer` interface represents the offset and orientation relative to the layer's `space`.

Value
-----

An `XRRigidTransform`.

Examples
--------

### Setting the equirect layer's position

This example code positions the layer two meters away from the origin of `xrReferenceSpace`.

```js
const equirectLayer = xrGlBinding.createEquirectLayer({
  space: xrReferenceSpace,
  viewPixelWidth: 512,
  viewPixelHeight: 512,
});

equirectLayer.transform = new XRRigidTransform({ z: -2 });
```

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

| Specification |
| --- |
| WebXR Layers API Level 1 # dom-xrequirectlayer-transform |

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

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

See also
--------

* `XRRigidTransform`
* `XREquirectLayer.space`


XREquirectLayer: space property - Web APIs

XREquirectLayer: space property
===============================

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

The **`space`** property of the `XREquirectLayer` interface represents the layer's spatial relationship with the user's physical environment.

Value
-----

An `XRSpace`.

Examples
--------

### Updating the equirect layer's space

The `XRWebGLBinding.createEquirectLayer()` method creates an equirect layer and requires a `space` property to be provided. The `XREquirectLayer.space` property can be used after layer creation to get the space used or to set it to a new one.

```js
const equirectLayer = xrGlBinding.createEquirectLayer({
  space: xrReferenceSpace,
  viewPixelWidth: 512,
  viewPixelHeight: 512,
});

equirectLayer.space = someOtherSpace;
```

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

| Specification |
| --- |
| WebXR Layers API Level 1 # dom-xrequirectlayer-space |

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

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

See also
--------

* `XRSpace`
* `XRWebGLBinding.createEquirectLayer()`


XREquirectLayer: radius property - Web APIs

XREquirectLayer: radius property
================================

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

The **`radius`** property of the `XREquirectLayer` interface represents the radius of the sphere.

Value
-----

A number representing the non-negative radius (in meters) of the sphere. Values of zero or infinity are treated as representing an infinite sphere. Setting `radius` to a value less than 0 will set it to 0.

Examples
--------

### Getting a layer's radius

The `XRWebGLBinding.createEquirectLayer()` method creates an equirect layer and allows specifying a `radius`. The `XREquirectLayer.radius` property can be used after layer creation to get the radius used or to set it to a new one.

```js
const equirectLayer = xrGlBinding.createEquirectLayer({
  space: xrReferenceSpace,
  viewPixelWidth: 1200,
  viewPixelHeight: 600,
  centralHorizontalAngle: 2 \* Math.PI,
  upperVerticalAngle: Math.PI / 2.0,
  lowerVerticalAngle: -Math.PI / 2.0,
  radius: 0,
});

equirectLayer.radius; // 0
```

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

| Specification |
| --- |
| WebXR Layers API Level 1 # dom-xrequirectlayer-radius |

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

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

See also
--------

* `XREquirectLayer.centralHorizontalAngle`
* `XREquirectLayer.lowerVerticalAngle`
* `XREquirectLayer.upperVerticalAngle`


XREquirectLayer: redraw event - Web APIs

XREquirectLayer: redraw event
=============================

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

The `redraw` event is sent to the `XREquirectLayer` object when the underlying resources of the layer are lost or when the XR Compositor can no longer reproject the layer. If this event is sent, authors should redraw the content of the layer in the next XR animation frame.

See also the `XRCompositionLayer.needsRedraw` property which is also available to `XREquirectLayer` objects through inheritance from `XRCompositionLayer`.

Syntax
------

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

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

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

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

An `XRLayerEvent`. Inherits from `Event`.

Event properties
----------------

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

`layer` Read only

The `XRLayer` which generated the event.

Examples
--------

### Using the `redraw` event

You can pass `redraw` to `addEventListener()`:

```js
equirectLayer.addEventListener("redraw", (event) => {
  // redraw the layer
});
```

Alternatively, you can use the `onredraw` event handler property to establish a handler for the `redraw` event:

```js
equirectLayer.onredraw = (event) => {
  // redraw the layer
};
```

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

| Specification |
| --- |
| WebXR Layers API Level 1 # eventdef-xrlayer-redraw |

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

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

See also
--------

* `XRCompositionLayer.needsRedraw`


BackgroundFetchUpdateUIEvent: BackgroundFetchUpdateUIEvent() constructor - Web APIs

BackgroundFetchUpdateUIEvent: BackgroundFetchUpdateUIEvent() constructor
========================================================================

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
**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`BackgroundFetchUpdateUIEvent()`** constructor creates a new `BackgroundFetchUpdateUIEvent` object. This constructor is not typically used as the browser creates these objects itself and provides them to background fetch event callbacks.

Syntax
------

```js
new BackgroundFetchEvent(type, options)
```

### Parameters

`type`

 A string with the name of the event.
 It is case-sensitive and browsers set it to `backgroundfetchsuccess` or `backgroundfetchfail`.

`options`

An object that, *in addition of the properties defined in `ExtendableEvent()`*, has the following properties:

`registration`

A `BackgroundFetchRegistration` object.

### Return value

A new `BackgroundFetchUpdateUIEvent` object.

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

| Specification |
| --- |
| Background Fetch # dom-backgroundfetchupdateuievent-backgroundfetchupdateuievent |

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

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


BackgroundFetchUpdateUIEvent: updateUI() method - Web APIs

BackgroundFetchUpdateUIEvent: updateUI() 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
**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`updateUI()`** method of the `BackgroundFetchUpdateUIEvent` interface updates the title and icon in the user interface to show the status of a background fetch.

This method may only be run once, to notify the user on a failed or a successful fetch.

Syntax
------

```js
updateUI(options)
```

### Parameters

`options` Optional

An object containing any of the following:

`icons` Optional

A list of one or more image resources, containing icons for use in the user interface. An image resource is an object containing:

`src`

A string which is a URL of an image.

`sizes` Optional

A string which is equivalent to a `<link>` `sizes` attribute.

`type` Optional

A string containing an image MIME type.

`label` Optional

A string providing a name for the associated image.

`title` Optional

A string containing the new title of the user interface.

### Return value

A `Promise`.

### Exceptions

`InvalidStateError` `DOMException`

Returned if any of the following are true:

* The `isTrusted` property is `false`.
* The `BackgroundFetchUpdateUIEvent` UI updated flag is already set, indicating that the `updateUI()` method has already been called.
* The `BackgroundFetchUpdateUIEvent` is not active.

Examples
--------

The following example demonstrates updating the UI with a title and image icon on a successful fetch.

```js
addEventListener("backgroundfetchsuccess", (event) => {
  event.updateUI({
    title: "Episode 5 ready to listen!",
    icon: {
      src: "path/to/success.ico",
      sizes: "16x16 32x32 64x64",
    },
  });
});
```

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

| Specification |
| --- |
| Background Fetch # background-fetch-update-ui-event-update-ui |

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

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


Presentation: receiver property - Web APIs

Presentation: receiver property
===============================

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

 The **read-only** `Presentation` attribute
 `receiver`, which is only available in browser contexts which are
 **receiving** a presentation, returns the
 `PresentationReceiver` object which can be used to access and communicate
 with the browser context which controls the presentation. This property is always
 `null` when accessed from outside a browser context which is receiving a
 presentation.

Value
-----

 If the code is running in a context which is receiving a presentation, the returned
 value is a `PresentationReceiver` which can then be used to communicate
 with the context which is the source of the presentation.

 If the current context is not receiving a presentation, `receiver` is
 `null`.

Examples
--------

### Determining whether or not the context is receiving a presentation

 You can easily determine whether or not the context is the receiver for a presentation
 by checking the value of `navigator.receiver`. If it's a non-null value, then
 the context is indeed receiving a presentation. If it's `null`, there's no
 incoming presentation.

```js
footer.textContent = navigator.receiver ? "Receiving presentation" : "(idle)";
```

### Accessing the connection list

 This example uses `receiver` to access the list of incoming connections and
 to build and display a list of those connections' ID strings.

```js
let listElem = document.getElementById("connectionview");

navigator.presentation.receiver.connectionList.then((connections) => {
  connections.forEach((aConnection) => {
    listElem.innerHTML += `<li>${aConnection.id}</li>`;
  });
});
```

 After getting access to the output list element in the variable
 `connectionView`, `navigator.receiver` is used to get a
 reference to the `PresentationReceiver` object for this context, and its
 `connectionList` is used to get a
 `Promise` which will be called when the list is available.

 The promise handler receives as its input parameter an array of the incoming
 connections. We iterate over these using `forEach()`,
 appending a new item to the `connectionView` list element for each
 connection.

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

| Specification |
| --- |
| Presentation API # dom-presentation-receiver |

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

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

See also
--------

* Presentation API
* `Presentation`
* `PresentationReceiver`


Presentation: defaultRequest property - Web APIs

Presentation: defaultRequest property
=====================================

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

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

In a controlling user agent, the **`defaultRequest`** attribute *MUST* return the default presentation request if any, otherwise `null`. In a receiving browsing context, it *MUST* return `null`.

If set by the controller, the value of the `defaultRequest` attribute *SHOULD* be used by the controlling user agent as the *default presentation request* for that controlling browsing context. If the document object's active sandboxing flag set has the sandboxed presentation browsing context flag set, the controlling user agent *SHOULD* act as if the default request is not set for that browsing context. When the controlling user agent wishes to initiate a `PresentationConnection` on the behalf of that browsing context, it *MUST* start a presentation using the default presentation request for the controller (as if the controller had called `defaultRequest.start()`).

The controlling user agent *SHOULD* initiate presentation using the default presentation request, only when the user has expressed an intention to do so via a user gesture. For example, by clicking a button in the browser.

**Note:** Some controlling user agents may allow the user to initiate a default presentation connection and select a presentation display with the same user gesture. For example, the browser chrome could allow the user to pick a display from a menu, or allow the user to tap on an Near Field Communications (NFC) enabled display. In this case, when the controlling user agent asks for permission while starting a presentation, the browser could offer that display as the default choice, or consider the gesture as granting permission for the display and bypass display selection entirely.

**Note:** If a controlling user agent does not support initiation of a presentation connection from the browser chrome, setting `defaultRequest` will have no effect.

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

| Specification |
| --- |
| Presentation API # dom-presentation-defaultrequest |

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

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


HTMLTableRowElement: insertCell() method - Web APIs

HTMLTableRowElement: insertCell() method
========================================

 The **`HTMLTableRowElement.insertCell()`** method inserts a new
 cell (`<td>`) into a table row (`<tr>`) and returns a
 reference to the cell.

**Note:** `insertCell()` inserts the cell directly into the
 row. The cell does not need to be appended separately
 with `Node.appendChild()` as would be the case if
 `Document.createElement()` had been used to create the new
 `<td>` element.

 You can not use `insertCell()` to create a new `<th>`
 element though.

Syntax
------

```js
insertCell()
insertCell(index)
```

`HTMLTableRowElement` is a reference to an HTML `<tr>`
 element.

### Parameters

`index` Optional

The cell index of the new cell. If `index` is `-1` or equal to the number of cells, the cell is appended as the last cell in the row. If `index` is omitted it defaults to `-1`.

### Return value

 An `HTMLTableCellElement` that references the new
 cell.

### Exceptions

`IndexSizeError` `DOMException`

Thrown if `index` is greater than the number of cells.

Examples
--------

 This example uses `HTMLTableElement.insertRow()` to append a new row to a
 table.

 We then use `insertCell(0)` to insert a new cell in the new row. (To be
 valid HTML, a `<tr>` must have at least one `<td>`
 element.) Finally, we add some text to the cell using
 `Document.createTextNode()` and `Node.appendChild()`.

### HTML

```html
<table id="my-table">
  <tr>
    <td>Row 1</td>
  </tr>
  <tr>
    <td>Row 2</td>
  </tr>
  <tr>
    <td>Row 3</td>
  </tr>
</table>
```

### JavaScript

```js
function addRow(tableID) {
  // Get a reference to the table
  let tableRef = document.getElementById(tableID);

  // Insert a row at the end of the table
  let newRow = tableRef.insertRow(-1);

  // Insert a cell in the row at index 0
  let newCell = newRow.insertCell(0);

  // Append a text node to the cell
  let newText = document.createTextNode("New bottom row");
  newCell.appendChild(newText);
}

// Call addRow() with the table's ID
addRow("my-table");
```

### Result

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

| Specification |
| --- |
| HTML Standard # dom-tr-insertcell-dev |

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

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

See also
--------

* `HTMLTableElement.insertRow()`
* The HTML element representing cells: `HTMLTableCellElement`


HTMLTableRowElement: rowIndex property - Web APIs

HTMLTableRowElement: rowIndex property
======================================

 The **`HTMLTableRowElement.rowIndex`** read-only property
 represents the position of a row in relation to the whole `<table>`.

 Even when the `<thead>`, `<tbody>`, and
 `<tfoot>` elements are out of order in the HTML, browsers render the
 table in the right order. Therefore the rows count from `<thead>` to
 `<tbody>`, from `<tbody>` to
 `<tfoot>`.

Value
-----

Returns the index of the row, or `-1` if the row is not part of a table.

Examples
--------

This example uses JavaScript to label all the row numbers in a table.

### HTML

```html
<table>
  <thead>
    <tr>
      <th>Item</th>
      <th>Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Bananas</td>
      <td>$2</td>
    </tr>
    <tr>
      <td>Oranges</td>
      <td>$8</td>
    </tr>
    <tr>
      <td>Top Sirloin</td>
      <td>$20</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>Total</td>
      <td>$30</td>
    </tr>
  </tfoot>
</table>
```

### JavaScript

```js
let rows = document.querySelectorAll("tr");

rows.forEach((row) => {
  let z = document.createElement("td");
  z.textContent = `(row #${row.rowIndex})`;
  row.appendChild(z);
});
```

### Result

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

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


Using the Web Storage API - Web APIs

Using the Web Storage API
=========================

The Web Storage API provides mechanisms by which browsers can securely store key/value pairs.

This article provides a walkthrough of how to make use of this technology.

Basic concepts
--------------

Storage objects are simple key-value stores, similar to objects, but they stay intact through page loads. The keys and the values are always strings (note that, as with objects, integer keys will be automatically converted to strings). You can access these values like an object, or with the `Storage.getItem()` and `Storage.setItem()` methods. These three lines all set the (same) colorSetting entry:

```js
localStorage.colorSetting = "#a4509b";
localStorage["colorSetting"] = "#a4509b";
localStorage.setItem("colorSetting", "#a4509b");
```

**Note:** It's recommended to use the Web Storage API (`setItem`, `getItem`, `removeItem`, `key`, `length`) to prevent the pitfalls associated with using plain objects as key-value stores.

The two mechanisms within Web Storage are as follows:

* `sessionStorage` maintains a separate storage area for each given origin that's available for the duration of the page session (as long as the browser is open, including page reloads and restores).
* `localStorage` does the same thing, but persists even when the browser is closed and reopened.

These mechanisms are available via the `Window.sessionStorage` and `Window.localStorage` properties (to be more precise, in supporting browsers the `Window` object implements the `WindowLocalStorage` and `WindowSessionStorage` objects, which the `localStorage` and `sessionStorage` properties are members of) — invoking one of these will create an instance of the `Storage` object, through which data items can be set, retrieved, and removed. A different Storage object is used for the `sessionStorage` and `localStorage` for each origin — they function and are controlled separately.

So, for example, initially calling `localStorage` on a document will return a `Storage` object; calling `sessionStorage` on a document will return a different `Storage` object. Both of these can be manipulated in the same way, but separately.

Feature-detecting localStorage
------------------------------

To be able to use localStorage, we should first verify that it is supported and available in the current browsing session.

### Testing for availability

**Note:** This API is available in current versions of all major browsers. Testing for availability is necessary only if you must support very old browsers, or in the limited circumstances described below.

Browsers that support localStorage have a property on the window object named `localStorage`. However, just asserting that the property exists may throw exceptions. If the `localStorage` object does exist, there is still no guarantee that the localStorage API is actually available, as various browsers offer settings that disable localStorage. So a browser may *support* localStorage, but not make it *available* to the scripts on the page.

For example, for a document viewed in a browser's private browsing mode, some browsers might give us an empty `localStorage` object with a quota of zero, effectively making it unusable. Conversely, we might get a legitimate `QuotaExceededError`, which means that we've used up all available storage space, but storage *is* actually *available*. Our feature detection should take these scenarios into account.

Here is a function that detects whether localStorage is both supported and available:

```js
function storageAvailable(type) {
  let storage;
  try {
    storage = window[type];
    const x = "\_\_storage\_test\_\_";
    storage.setItem(x, x);
    storage.removeItem(x);
    return true;
  } catch (e) {
    return (
      e instanceof DOMException &&
      // everything except Firefox
      (e.code === 22 ||
        // Firefox
        e.code === 1014 ||
        // test name field too, because code might not be present
        // everything except Firefox
        e.name === "QuotaExceededError" ||
        // Firefox
        e.name === "NS\_ERROR\_DOM\_QUOTA\_REACHED") &&
      // acknowledge QuotaExceededError only if there's something already stored
      storage &&
      storage.length !== 0
    );
  }
}
```

And here is how you would use it:

```js
if (storageAvailable("localStorage")) {
  // Yippee! We can use localStorage awesomeness
} else {
  // Too bad, no localStorage for us
}
```

You can test for sessionStorage instead by calling `storageAvailable('sessionStorage')`.

See here for a brief history of feature-detecting localStorage.

Example
-------

To illustrate some typical web storage usage, we have created an example, imaginatively called **Web Storage Demo**. The landing page provides controls that can be used to customize the color, font, and decorative image:

![Web storage example with text box to choose the color by entering a hex value, and two dropdown menus to choose the font style, and decorative image.](/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API/landing.png)When you choose different options, the page is instantly updated; in addition, your choices are stored in `localStorage`, so that when you leave the page and load it again, later on, your choices are remembered.

We have also provided an event output page — if you load this page in another tab, then make changes to your choices in the landing page, you'll see the updated storage information outputted as a `StorageEvent` is fired.

![Event output page](/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API/event-output.png)

**Note:** As well as viewing the example pages live using the above links, you can also check out the source code.

### Testing whether your storage has been populated

To start with, in main.js, we test whether the storage object has already been populated (i.e., the page was previously accessed):

```js
if (!localStorage.getItem("bgcolor")) {
  populateStorage();
} else {
  setStyles();
}
```

The `Storage.getItem()` method is used to get a data item from storage; in this case, we are testing to see whether the `bgcolor` item exists; if not, we run `populateStorage()` to add the existing customization values to the storage. If there are already values there, we run `setStyles()` to update the page styling with the stored values.

**Note:** You could also use `Storage.length` to test whether the storage object is empty or not.

### Getting values from storage

 As noted above, values can be retrieved from storage using `Storage.getItem()`.
 This takes the key of the data item as an argument, and returns the data value.

For example:

```js
function setStyles() {
  const currentColor = localStorage.getItem("bgcolor");
  const currentFont = localStorage.getItem("font");
  const currentImage = localStorage.getItem("image");

  document.getElementById("bgcolor").value = currentColor;
  document.getElementById("font").value = currentFont;
  document.getElementById("image").value = currentImage;

  htmlElem.style.backgroundColor = `#${currentColor}`;
  pElem.style.fontFamily = currentFont;
  imgElem.setAttribute("src", currentImage);
}
```

 Here, the first three lines grab the values from local storage.
 Next, we set the values displayed in the form elements to those values, so that they keep in sync when you reload the page.
 Finally, we update the styles/decorative image on the page, so your customization options come up again on reload.

### Setting values in storage

`Storage.setItem()` is used both to create new data items, and (if the data item already exists) update existing values. This takes two arguments — the key of the data item to create/modify, and the value to store in it.

```js
function populateStorage() {
  localStorage.setItem("bgcolor", document.getElementById("bgcolor").value);
  localStorage.setItem("font", document.getElementById("font").value);
  localStorage.setItem("image", document.getElementById("image").value);

  setStyles();
}
```

The `populateStorage()` function sets three items in local storage — the background color, font, and image path. It then runs the `setStyles()` function to update the page styles, etc.

We've also included an `onchange` handler on each form element so that the data and styling are updated whenever a form value is changed:

```js
bgcolorForm.onchange = populateStorage;
fontForm.onchange = populateStorage;
imageForm.onchange = populateStorage;
```

`Storage` only supports storing and retrieving strings. If you want to save other data types, you have to convert them to strings. For plain objects and arrays, you can use `JSON.stringify()`.

```js
const person = { name: "Alex" };
localStorage.setItem("user", person);
console.log(localStorage.getItem("user")); // "[object Object]"; not useful!
localStorage.setItem("user", JSON.stringify(person));
console.log(JSON.parse(localStorage.getItem("user"))); // { name: "Alex" }
```

However, there's no generic way to store arbitrary data types. Furthermore, the retrieved object is a deep copy of the original object and mutations to it do not affect the original object.

### Responding to storage changes with the StorageEvent

The `StorageEvent` is fired whenever a change is made to the `Storage` object (note that this event is not fired for sessionStorage changes). This won't work on the same page that is making the changes — it is really a way for other pages on the domain using the storage to sync any changes that are made. Pages on other domains can't access the same storage objects.

On the events page (see events.js) the only JavaScript is as follows:

```js
window.addEventListener("storage", (e) => {
  document.querySelector(".my-key").textContent = e.key;
  document.querySelector(".my-old").textContent = e.oldValue;
  document.querySelector(".my-new").textContent = e.newValue;
  document.querySelector(".my-url").textContent = e.url;
  document.querySelector(".my-storage").textContent = JSON.stringify(
    e.storageArea,
  );
});
```

Here we add an event listener to the `window` object that fires when the `Storage` object associated with the current origin is changed. As you can see above, the event object associated with this event has a number of properties containing useful information — the key of the data that changed, the old value before the change, the new value after that change, the URL of the document that changed the storage, and the storage object itself (which we've stringified so you can see its content).

### Deleting data records

Web Storage also provides a couple of simple methods to remove data. We don't use these in our demo, but they are very simple to add to your project:

* `Storage.removeItem()` takes a single argument — the key of the data item you want to remove — and removes it from the storage object for that domain.
* `Storage.clear()` takes no arguments, and empties the entire storage object for that domain.
Specifications
--------------

| Specification |
| --- |
| HTML Standard # dom-localstorage-dev |
| HTML Standard # dom-sessionstorage-dev |

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

### api.Window.localStorage

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

### api.Window.sessionStorage

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

See also
--------

* Web Storage API landing page


ImageDecoder: completed property - Web APIs

ImageDecoder: completed property
================================

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 **`completed`** read-only property of the `ImageDecoder` interface returns a promise that resolves once encoded data has finished buffering.

Value
-----

A `Promise` that resolves with `undefined` once `ImageDecoder.complete` is `true`.

Examples
--------

In the following example the value of `completed` will be `undefined` once the promise resolves.

```js
let completed = await imageDecoder.completed;
console.log(completed);
```

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

| Specification |
| --- |
| WebCodecs # dom-imagedecoder-completed |

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

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


ImageDecoder: complete property - Web APIs

ImageDecoder: complete property
===============================

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 **`complete`** read-only property of the `ImageDecoder` interface returns true if encoded data has completed buffering.

Value
-----

A `boolean`, `true` if buffering is complete.

Examples
--------

The following example prints the value of `complete` to the console.

```js
console.log(imageDecoder.complete);
```

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

| Specification |
| --- |
| WebCodecs # dom-imagedecoder-complete |

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

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


ImageDecoder: decode() method - Web APIs

ImageDecoder: decode() 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 **`decode()`** method of the `ImageDecoder` interface enqueues a control message to decode the frame of an image.

Syntax
------

```js
decode()
decode(options)
```

### Parameters

`options` Optional

An object containing the following members:

`frameIndex` Optional

An integer representing the index of the frame to decode. Defaults to `0` (the first frame).

`completeFramesOnly` Optional

A `boolean` defaulting to `true`. When `false` indicates that for progressive images the decoder may output an image with reduced detail. When `false`, the promise returned by `decode()` will resolve exactly once for each new level of detail.

### Return value

A `promise` that resolves with an object containing the following members:

`image`

A `VideoFrame` containing the decoded image.

`complete`

A `boolean`, if `true` indicates that `image` contains the final full-detail output.

### Exceptions

If an error occurs, the promise will resolve with following exception:

`InvalidStateError` `DOMException`

Returned if any of the following conditions apply:

* `close` is true, meaning `close()` has already been called.
* The requested frame does not exist.

Examples
--------

### Synchronous decoding of a completed image frame

The following example decodes the second frame (at index `1`) and prints the resulting `VideoFrame` to the console.

```js
let result = await imageDecoder.decode({ frameIndex: 1 });
console.log(result.image);
```

### Partial decoding of a progressive image frame

The following example decodes the first frame repeatedly until its complete:

```js
let complete = false;
while (!complete) {
  // The promise returned by `decode()` will only resolve when a new
  // level of detail is available or the frame is complete. I.e.,
  // calling `decode()` in a loop like this is won't needlessly spin.
  let result = await imageDecode.decode({ completeFramesOnly: false });

  // Do something with `result.image`.

  complete = result.complete;
}
```

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

| Specification |
| --- |
| WebCodecs # dom-imagedecoder-decode |

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

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


ImageDecoder: isTypeSupported() static method - Web APIs

ImageDecoder: isTypeSupported() static 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 **`ImageDecoder.isTypeSupported()`** static method checks if a given MIME type can be decoded by the user agent.

Syntax
------

```js
ImageDecoder.isTypeSupported(type)
```

### Parameters

`type`

A string containing the MIME type to check for decoding support.

### Return value

A `promise` that resolves with a boolean value indicating whether images with a format of `type` can be decoded by the API.

Examples
--------

The following example checks if GIF and PCX images are supported for decoding and prints the result to the console.

```js
let isGifSupported = await ImageDecoder.isTypeSupported("image/gif");
console.log(`GIF supported: ${isGifSupported}`); // Likely true.

let isPcxSupported = await ImageDecoder.isTypeSupported("image/pcx");
console.log(`PCX supported: ${isPcxSupported}`); // Probably false
```

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

| Specification |
| --- |
| WebCodecs # dom-imagedecoder-istypesupported |

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

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


ImageDecoder: tracks property - Web APIs

ImageDecoder: tracks property
=============================

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 **`tracks`** read-only property of the `ImageDecoder` interface returns a list of the tracks in the encoded image data.

Value
-----

An `ImageTrackList`.

Examples
--------

The following example prints the value of `tracks` to the console. This will be an `ImageTrackList` object.

```js
console.log(imageDecoder.tracks);
```

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

| Specification |
| --- |
| WebCodecs # dom-imagedecoder-tracks |

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

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


ImageDecoder: reset() method - Web APIs

ImageDecoder: reset() 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 **`reset()`** method of the `ImageDecoder` interface aborts all pending `decode()` operations; rejecting all pending promises. All other state will be unchanged. Class methods can continue to be invoked after `reset()`. E.g., calling `decode()` after `reset()` is permitted.

Syntax
------

```js
reset()
```

### Parameters

None.

### Return value

None (`undefined`).

Examples
--------

The following example resets the `ImageDecoder`.

```js
for (let i = 0; i < imageDecoder.tracks.selectedTrack.frameCount; ++i)
  imageDecoder.decode({ frameIndex: i }).catch(console.log);
imageDecoder.reset();
imageDecoder.decode({ frameIndex: 0 }).then(console.log);
```

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

| Specification |
| --- |
| WebCodecs # dom-imagedecoder-reset |

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

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


ImageDecoder: type property - Web APIs

ImageDecoder: type property
===========================

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 **`type`** read-only property of the `ImageDecoder` interface reflects the MIME type configured during construction.

Value
-----

A string containing the configured MIME type.

Examples
--------

The following example prints the value of `type` to the console.

```js
console.log(imageDecoder.type);
```

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

| Specification |
| --- |
| WebCodecs # dom-imagedecoder-type |

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

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


ImageDecoder: close() method - Web APIs

ImageDecoder: close() 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 **`close()`** method of the `ImageDecoder` interface ends all pending work and releases system resources.

Syntax
------

```js
close()
```

### Parameters

None.

### Return value

None (`undefined`).

Examples
--------

The following example closes the `ImageDecoder`.

```js
imageDecoder.close();
```

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

| Specification |
| --- |
| WebCodecs # dom-imagedecoder-close |

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

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


ImageDecoder: ImageDecoder() constructor - Web APIs

ImageDecoder: ImageDecoder() constructor
========================================

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 **`ImageDecoder()`** constructor creates a new `ImageDecoder` object which unpacks and decodes image data.

Syntax
------

```js
new ImageDecoder(init)
```

### Parameters

`init`

An object containing the following members:

`type`

A string containing the MIME type of the image file to be decoded.

`data`

An `ArrayBuffer`, a `TypedArray`, a `DataView`, or a `ReadableStream` of bytes representing an encoded image type as described by `type`.

`premultiplyAlpha` Optional

Specifies whether the decoded image's color channels should be premultiplied by the alpha channel. If not provided set as `"default"`:

* `"none"`
* `"premultiply"`
* `"default"`

`colorSpaceConversion` Optional

Specifies whether the image should be decoded using color space conversion. If not provided set as `"default"`. The value `"default"` indicates that implementation-specific behavior is used:

* `"none"`
* `"default"`

`desiredWidth` Optional

An integer indicating the desired width for the decoded output. Has no effect unless the image codec supports variable resolution decoding.

`desiredHeight` Optional

An integer indicating the desired height for the decoded output. Has no effect unless the image codec supports variable resolution decoding.

`preferAnimation` Optional

A `Boolean` indicating whether the initial track selection should prefer an animated track.

`transfer`

An array of `ArrayBuffer`s that `ImageDecoder` will detach and take ownership of. If the array contains the `ArrayBuffer` backing `data`, `ImageDecoder` will use that buffer directly instead of copying from it.

Examples
--------

The following example creates a new `ImageDecoder` with the required options.

```js
let init = {
  type: "image/png",
  data: imageByteStream,
};

let imageDecoder = new ImageDecoder(init);
```

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

| Specification |
| --- |
| WebCodecs # dom-imagedecoder-imagedecoder |

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

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


XRLightEstimate: primaryLightIntensity property - Web APIs

XRLightEstimate: primaryLightIntensity property
===============================================

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

The *read-only* **`primaryLightIntensity`** property of the `XRLightEstimate` interface returns a `DOMPointReadOnly` representing the intensity of the primary light source from the `probeSpace` of an `XRLightProbe`.

Value
-----

A `DOMPointReadOnly` object where an RGB value is mapped to the `x`, `y`, and `z` values. The `w` value is always `1.0`. If no estimated values from the user's environment are available, the point will be `{x: 0.0, y: 0.0, z: 0.0, w: 1.0}`, representing no illumination.

Examples
--------

 Within an `XRFrame` loop, you can use the `primaryLightDirection` and `primaryLightIntensity` properties
 to render shadows based on the most prominent light source, for example.

```js
const lightProbe = await xrSession.requestLightProbe();

// frame loop
function onXRFrame(time, xrFrame) {
  let lightEstimate = xrFrame.getLightEstimate(lightProbe);

  // Render lights

  // Available properties
  lightEstimate.primaryLightDirection;
  lightEstimate.primaryLightIntensity;
}
```

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

| Specification |
| --- |
| WebXR Lighting Estimation API Level 1 # dom-xrlightestimate-primarylightintensity |

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

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

See also
--------

* `XRLightEstimate.primaryLightDirection`
* `XRLightProbe.probeSpace`


XRLightEstimate: primaryLightDirection property - Web APIs

XRLightEstimate: primaryLightDirection property
===============================================

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

The *read-only* **`primaryLightDirection`** property of the `XRLightEstimate` interface returns a `DOMPointReadOnly` representing the direction to the primary light source from the `probeSpace` of an `XRLightProbe`.

Value
-----

A `DOMPointReadOnly` object. If no estimated values from the user's environment are available, the point will be `{ x: 0.0, y: 1.0, z: 0.0, w: 0.0 }`, representing a light shining straight down from above.

Examples
--------

 Within an `XRFrame` loop, you can use the `primaryLightDirection` and `primaryLightIntensity` properties
 to render shadows based on the most prominent light source, for example.

```js
const lightProbe = await xrSession.requestLightProbe();

// frame loop
function onXRFrame(time, xrFrame) {
  let lightEstimate = xrFrame.getLightEstimate(lightProbe);

  // Render lights

  // Available properties
  lightEstimate.primaryLightDirection;
  lightEstimate.primaryLightIntensity;
}
```

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

| Specification |
| --- |
| WebXR Lighting Estimation API Level 1 # dom-xrlightestimate-primarylightdirection |

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

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

See also
--------

* `XRLightEstimate.primaryLightIntensity`
* `XRLightProbe.probeSpace`


XRLightEstimate: sphericalHarmonicsCoefficients property - Web APIs

XRLightEstimate: sphericalHarmonicsCoefficients property
========================================================

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

The *read-only* **`sphericalHarmonicsCoefficients`** property of the `XRLightEstimate` interface returns a `Float32Array` containing 9 spherical harmonics coefficients.

Spherical harmonic lighting is a technique that uses spherical functions instead of standard lighting equations. See Wikipedia for more information.

Value
-----

A `Float32Array` containing 9 spherical harmonics coefficients. The array contains 27 elements in total, with every 3 elements defining red, green, and blue components for each coefficient.

The first 3 elements must be a valid lighting estimate component; the rest may be 0 due to privacy settings or limitations of the device to provide more data.

Examples
--------

Within an `XRFrame` loop, you can use the `sphericalHarmonicsCoefficients` property to light the scene.

```js
const lightProbe = await xrSession.requestLightProbe();

// frame loop
function onXRFrame(time, xrFrame) {
  let lightEstimate = xrFrame.getLightEstimate(lightProbe);

  // Render lights using lightEstimate.sphericalHarmonicsCoefficients
}
```

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

| Specification |
| --- |
| WebXR Lighting Estimation API Level 1 # dom-xrlightestimate-sphericalharmonicscoefficients |

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

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

See also
--------

* `XRFrame.getLightEstimate()`


Clipboard: write() method - Web APIs

Clipboard: write() method
=========================

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

 The **`write()`** method of the `Clipboard` interface writes arbitrary data to the clipboard, such as images, fulfilling the returned `Promise` on completion.
 This can be used to implement cut and copy functionality.

 The method can in theory write arbitrary data (unlike `writeText()`, which can only write text).
 Browsers commonly support writing text, HTML, and PNG image data — see browser compatibility for more information.

Syntax
------

```js
write(data)
```

### Parameters

`data`

An array of `ClipboardItem` objects containing data to be written to the clipboard.

### Return value

 A `Promise` which is resolved when the data has been written to the clipboard.
 Note that if the underlying OS does not support multiple native clipboard items on the system clipboard, then only the first `ClipboardItem` in the array is written.

The promise is rejected if the clipboard is unable to write to the clipboard.

### Exceptions

`NotAllowedError` `DOMException`

Thrown if writing to the clipboard is not allowed.

Security considerations
-----------------------

Writing to the clipboard can only be done in a secure context.

Additional security requirements are covered in the Security consideration section of the API overview topic.

Examples
--------

### Write text to the clipboard

 This example function replaces the current contents of the clipboard with a specified string when a button is pressed.
 Note that for this particular case, you could just as readily use `Clipboard.writeText()`.

```js
button.addEventListener("click", setClipboard("<empty clipboard>"));

async function setClipboard(text) {
  const type = "text/plain";
  const blob = new Blob([text], { type });
  const data = [new ClipboardItem({ [type]: blob })];
  await navigator.clipboard.write(data);
}
```

 The `setClipboard()` method begins by creating a new a `Blob` object.
 This object is required to construct a `ClipboardItem` object which is sent to the clipboard.
 The `Blob` constructor takes in the content we want to copy and its type.
 This `Blob` object can be derived from many sources; for example, a canvas.

 Next, we create a new `ClipboardItem` object into which the blob will be placed for sending to the clipboard.
 The key of the object passed to the `ClipboardItem` constructor indicates the content type, the value indicates the content.
 Then `write()` is called with `await`.
 A `try..catch` block could be used to catch any errors writing the data.

### Write canvas contents to the clipboard

This example writes the canvas to a blob, using the default MIME type of `image/png`, and then writes the blob to the clipboard.

```js
// Get canvas can add an event handler for the click event.
const canvas = document.getElementById("canvas");
canvas.addEventListener("click", copyCanvasContentsToClipboard());

async function copyCanvasContentsToClipboard() {
  // Copy canvas to blob
  const blob = await canvas.toBlob();
  // Create ClipboardItem with blob and it's type, and add to an array
  const data = [new ClipboardItem({ [blob.type]: blob })];
  // Write the data to the clipboard
  await navigator.clipboard.write(data);
}
```

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

| Specification |
| --- |
| Clipboard API and events # dom-clipboard-write |

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

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

See also
--------

* Clipboard API
* Image support for Async Clipboard article
* `Clipboard.writeText()`
* `Clipboard.read()`
* `Clipboard.readText()`


Clipboard: writeText() method - Web APIs

Clipboard: writeText() method
=============================

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

The **`writeText()`** method of the `Clipboard` interface writes the specified text to the system clipboard, returning a `Promise` that is resolved once the system clipboard has been updated.

Syntax
------

```js
writeText(newClipText)
```

### Parameters

`newClipText`

The string to be written to the clipboard.

### Return value

A `Promise` that is resolved once the clipboard's contents have been updated.

### Exceptions

`NotAllowedError` `DOMException`

Thrown if writing to the clipboard is not allowed.

Security considerations
-----------------------

Writing to the clipboard can only be done in a secure context.

Additional security requirements are covered in the Security consideration section of the API overview topic.

Examples
--------

This example sets the clipboard's contents to the string "<empty clipboard>".

```js
button.addEventListener("click", writeClipboardText("<empty clipboard>"));

async function writeClipboardText(text) {
  try {
    await navigator.clipboard.writeText(text);
  } catch (error) {
    console.error(error.message);
  }
}
```

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

| Specification |
| --- |
| Clipboard API and events # dom-clipboard-writetext |

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

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

See also
--------

* Clipboard API
* Image support for Async Clipboard article
* `Clipboard.write()`
* `Clipboard.read()`
* `Clipboard.readText()`


Clipboard: read() method - Web APIs

Clipboard: read() method
========================

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

The **`read()`** method of the `Clipboard` interface requests a copy of the clipboard's contents, fulfilling the returned `Promise` with the data.

 The method can in theory return arbitrary data (unlike `readText()`, which can only return text).
 Browsers commonly support reading text, HTML, and PNG image data — see browser compatibility for more information.

Syntax
------

```js
read()
read(formats)
```

### Parameters

`formats` Optional

An optional object with the following properties:

`unsanitized` Optional

An `Array` of strings containing MIME types of data formats that should not be sanitized when reading from the clipboard.

Certain browsers may sanitize the clipboard data when it is read, to prevent malicious content from being pasted into the document. For example, Chrome (and other Chromium-based browsers) sanitizes HTML data by stripping `<script>` tags and other potentially dangerous content. Use the `unsanitized` array to specify a list of MIME types that should not be sanitized.

### Return value

A `Promise` that resolves with an array of `ClipboardItem` objects containing the clipboard's contents.

### Exceptions

`NotAllowedError` `DOMException`

Thrown if the reading from the clipboard is not allowed.

Security considerations
-----------------------

Reading from the clipboard can only be done in a secure context.

Additional security requirements are covered in the Security consideration section of the API overview topic.

Examples
--------

### Reading image data from clipboard

This example uses the `read()` method to read image data from the clipboard and paste it into an `<img>` element.

#### HTML

```html
<img id="source" src="butterfly.jpg" alt="A butterfly" />
<img id="destination" />
<button id="reload" type="button">Reload</button>
<p id="log"></p>
```

#### CSS

```css
img {
  height: 100px;
  width: 100px;
  margin: 0 1rem;
  border: 1px solid black;
}
#reload {
  display: block;
  margin: 0 1rem;
}
```

#### JavaScript

This code provides a mechanism to log any errors to the element with id `log`.

```js
const logElement = document.querySelector("#log");
function log(text) {
  logElement.innerText = `Error: ${text}`;
}
```

We also add code to reload and clear the example when the "Reload" button is pressed.

```js
const reload = document.querySelector("#reload");

reload.addEventListener("click", () => {
  window.location.reload(true);
});
```

 The remaining code reads the clipboard when the destination element is clicked and copies the image data into the `destinationImage` element.
 It logs an error if it is unable to use the `read()` method, or if the clipboard does not contain data in PNG format.

```js
const destinationImage = document.querySelector("#destination");
destinationImage.addEventListener("click", pasteImage);

async function pasteImage() {
  try {
    const clipboardContents = await navigator.clipboard.read();
    for (const item of clipboardContents) {
      if (!item.types.includes("image/png")) {
        throw new Error("Clipboard does not contain PNG image data.");
      }
      const blob = await item.getType("image/png");
      destinationImage.src = URL.createObjectURL(blob);
    }
  } catch (error) {
    log(error.message);
  }
}
```

#### Result

 Copy the butterfly image on the left by right-clicking the image and selecting "Copy image" from the context menu.
 Then click on the empty frame on the right.
 The example will fetch the image data from the clipboard and display the image in the empty frame.

**Note:** If prompted, grant permission in order to paste the image.

### Reading data from the clipboard

This example uses the `read()` method to read data from the clipboard and log whatever data is stored in the clipboard.

This differs from the previous version in that it will display text, HTML, and image `ClipboardItem` objects (rather than just images).

#### HTML

```html
<img id="source\_jpg" src="butterfly.jpg" alt="JPG butterfly image" />
<div id="destination">Click here to copy clipboard data.</div>
<button id="reload" type="button">Reload</button>
<p id="log"></p>
```

#### CSS

```css
img {
  height: 100px;
  width: 100px;
  margin: 0 1rem;
  border: 1px solid black;
}

#destination {
  min-height: 300px;
  min-width: 90%;
  margin: 0 1rem;
  border: 1px solid black;
}

#reload {
  display: block;
  margin: 0 1rem;
}
```

#### JavaScript

This code provides a mechanism to log any errors to the element with id `log`.

```js
const logElement = document.querySelector("#log");
function log(text) {
  logElement.innerText = `Error: ${text}`;
}
```

We also add code to reload and clear the example when the "Reload" button is pressed.

```js
const reload = document.querySelector("#reload");

reload.addEventListener("click", () => {
  window.location.reload(true);
});
```

 The remaining code reads the clipboard when the destination element is clicked and displays each `ClipboardItem` element along with its MIME type.
 It logs an error it is unable to use the `read()` method, or if the clipboard contains any other MIME type.

```js
const destinationDiv = document.querySelector("#destination");
destinationDiv.addEventListener("click", pasteData);

async function pasteData() {
  destinationDiv.innerText = ""; //Clear inner text
  try {
    const clipboardContents = await navigator.clipboard.read();
    for (const item of clipboardContents) {
      for (const mimeType of item.types) {
        const mimeTypeElement = document.createElement("p");
        mimeTypeElement.innerText = `MIME type: ${mimeType}`;
        destinationDiv.appendChild(mimeTypeElement);
        if (mimeType === "image/png") {
          const pngImage = new Image(); // Image constructor
          pngImage.src = "image1.png";
          pngImage.alt = "PNG image from clipboard";
          const blob = await item.getType("image/png");
          pngImage.src = URL.createObjectURL(blob);
          destinationDiv.appendChild(pngImage);
        } else if (mimeType === "text/html") {
          const blob = await item.getType("text/html");
          const blobText = await blob.text();
          const clipHTML = document.createElement("pre");
          clipHTML.innerText = blobText;
          destinationDiv.appendChild(clipHTML);
        } else if (mimeType === "text/plain") {
          const blob = await item.getType("text/plain");
          const blobText = await blob.text();
          const clipPlain = document.createElement("pre");
          clipPlain.innerText = blobText;
          destinationDiv.appendChild(clipPlain);
        } else {
          throw new Error(`${mimeType} not supported.`);
        }
      }
    }
  } catch (error) {
    log(error.message);
  }
}
```

#### Result

 Copy some text or the butterfly (JPG) image below (to copy images right-click on them and then select "Copy image" from the context menu).
 Select the indicated frame below to paste this information from the clipboard into the frame.

Notes:

* Even though the butterfly image is a JPG file, when read from the clipboard it is a PNG.
* If prompted, you will need to grant permission in order to paste the image.
* This may not work on chromium browsers as the sample frame is not granted the Permissions-Policy `clipboard-read` and `clipboard-write` permissions (required by Chromium browsers).
### Reading unsanitized HTML from the clipboard

This example uses the `formats` parameter to read HTML data from the clipboard and get the code in its original form, without the browser sanitizing it first.

#### HTML

```html
<textarea id="source" rows="5">
  <style>h1 {color: red;} p {color: blue;}</style>
  <h1>Hello world!</h1>
  <p>This is a test.</p>
  <script>alert('Hello world!');</script>
</textarea>
<button id="copy">Copy HTML</button>
<button id="paste\_normal">Paste HTML</button>
<button id="paste\_unsanitized">Paste unsanitized HTML</button>
<textarea id="destination" rows="5"></textarea>
```

#### CSS

```css
body {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 5px;
}

textarea {
  grid-column: 1 / span 3;
}
```

#### JavaScript

```js
const copyButton = document.getElementById("copy");
const pasteButton = document.getElementById("paste\_normal");
const pasteUnsanitizedButton = document.getElementById("paste\_unsanitized");
const sourceTextarea = document.getElementById("source");
const destinationTextarea = document.getElementById("destination");

copyButton.addEventListener("click", async () => {
  const text = sourceTextarea.value;
  const type = "text/html";
  const blob = new Blob([text], { type });
  const data = [new ClipboardItem({ [type]: blob })];

  try {
    await navigator.clipboard.write(data);
  } catch (error) {
    destinationTextarea.value = `Clipboard write failed: ${error}`;
  }
});

async function getHTMLFromClipboardContents(clipboardContents) {
  for (const item of clipboardContents) {
    if (item.types.includes("text/html")) {
      const blob = await item.getType("text/html");
      const blobText = await blob.text();
      return blobText;
    }
  }

  return null;
}

pasteButton.addEventListener("click", async () => {
  try {
    const clipboardContents = await navigator.clipboard.read();
    const html = await getHTMLFromClipboardContents(clipboardContents);
    destinationTextarea.value =
      html || "Could not find HTML data in the clipboard.";
  } catch (error) {
    destinationTextarea.value = `Clipboard read failed: ${error}`;
  }
});

pasteUnsanitizedButton.addEventListener("click", async () => {
  try {
    const clipboardContents = await navigator.clipboard.read({
      unsanitized: ["text/html"],
    });
    const html = await getHTMLFromClipboardContents(clipboardContents);
    destinationTextarea.value =
      html || "Could not find HTML data in the clipboard.";
  } catch (error) {
    destinationTextarea.value = `Clipboard read failed: ${error}`;
  }
});
```

#### Result

First click the "Copy HTML" button to write the HTML code from the first textarea to the clipboard. Then either click the "Paste HTML" button or the "Paste unsanitized HTML" button to paste the sanitized or unsanitized HTML code into the second textarea.

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

| Specification |
| --- |
| Clipboard API and events # dom-clipboard-read |

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

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

See also
--------

* Clipboard API
* Unblocking clipboard access on web.dev
* Unsanitized HTML in the Async Clipboard API on developer.chrome.com
* `Clipboard.readText()`
* `Clipboard.writeText()`
* `Clipboard.write()`


Clipboard: readText() method - Web APIs

Clipboard: readText() method
============================

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

The **`readText()`** method of the `Clipboard` interface returns a `Promise` which fulfils with a copy of the textual contents of the system clipboard.

**Note:** To read non-text contents from the clipboard, use the `read()` method instead.
 You can write text to the clipboard using `writeText()`.

Syntax
------

```js
readText()
```

### Parameters

None.

### Return value

A `Promise` that resolves with a string containing the textual contents of the clipboard.

Returns an empty string if the clipboard is empty, does not contain text, or does not include a textual representation among the objects representing the clipboard's contents.

### Exceptions

`NotAllowedError` `DOMException`

Thrown if the access to read the clipboard is not allowed.

`NotFoundError` `DOMException`

Thrown if the clipboard indicates that it contains data that can be represented as a text but is unable to provide a textual representation.

Security considerations
-----------------------

Reading from the clipboard can only be done in a secure context.

Additional security requirements are covered in the Security consideration section of the API overview topic.

Examples
--------

This example retrieves the textual contents of the clipboard and inserts the returned text into a selected element's contents.

```js
const destination = document.getElementById("outbox");
destinationImage.addEventListener("click", () => {
  navigator.clipboard
    .readText()
    .then((clipText) => (destination.innerText = clipText));
});
```

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

| Specification |
| --- |
| Clipboard API and events # dom-clipboard-readtext |

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

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

See also
--------

* Clipboard API
* Image support for Async Clipboard article
* `Clipboard.read()`
* `Clipboard.writeText()`
* `Clipboard.write()`


BackgroundFetchEvent: registration property - Web APIs

BackgroundFetchEvent: registration property
===========================================

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
**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`registration`** read-only property of the `BackgroundFetchEvent` interface returns a `BackgroundFetchRegistration` object.

Value
-----

A `BackgroundFetchRegistration`.

Examples
--------

In this example, if the user clicks on the user interface displaying the download progress, this fires the `onbackgroundfetchclick` event. The current `BackgroundFetchRegistration` is returned by calling `event.registration`.

```js
addEventListener("backgroundfetchclick", (event) => {
  console.log(event.registration);
});
```

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

| Specification |
| --- |
| Background Fetch # dom-backgroundfetchevent-registration |

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

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


BackgroundFetchEvent: BackgroundFetchEvent() constructor - Web APIs

BackgroundFetchEvent: BackgroundFetchEvent() constructor
========================================================

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
**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`BackgroundFetchEvent()`** constructor creates a new `BackgroundFetchEvent` object. This constructor is not typically used as the browser creates these objects itself and provides them to background fetch event callbacks.

Syntax
------

```js
new BackgroundFetchEvent(type, options)
```

### Parameters

`type`

 A string with the name of the event.
 It is case-sensitive and browsers set it to `backgroundfetchabort` or `backgroundfetchclick`.

`options`

An object that, *in addition of the properties defined in `ExtendableEvent()`*, has the following properties:

`registration`

A `BackgroundFetchRegistration` object.

### Return value

A new `BackgroundFetchEvent` object.

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

| Specification |
| --- |
| Background Fetch # dom-backgroundfetchevent-backgroundfetchevent |

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

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


MessagePort: close() method - Web APIs

MessagePort: close() method
===========================

 The **`close()`** method of the `MessagePort`
 interface disconnects the port, so it is no longer active. This stops the flow of
 messages to that port.

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

Syntax
------

```js
close()
```

### Parameters

None.

### Return value

None (`undefined`).

Examples
--------

 In the following code block, you can see a `handleMessage` handler function,
 run when a message is sent back to this document using
 `EventTarget.addEventListener`.

```js
channel.port1.addEventListener("message", handleMessage, false);
function handleMessage(e) {
  para.innerHTML = e.data;
  textInput.value = "";
}

channel.port1.start();
```

You could stop messages being sent at any time using

```js
channel.port1.close();
```

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

| Specification |
| --- |
| HTML Standard # dom-messageport-close-dev |

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

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

See also
--------

* Using channel messaging


MessagePort: postMessage() method - Web APIs

MessagePort: postMessage() method
=================================

 The **`postMessage()`** method of the
 `MessagePort` interface sends a message from the port, and optionally,
 transfers ownership of objects to other browsing contexts.

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

Syntax
------

```js
postMessage(message)
postMessage(message, options)
postMessage(message, transfer)
```

### Parameters

`message`

The message you want to send through the channel. This can be of any basic data type. Multiple data items can be sent as an array.

`options` Optional

An optional object containing a `transfer` field with an array of transferable objects to transfer ownership of. The ownership of these objects is given to the destination side and they are no longer usable on the sending side.

`transfer` Optional

An optional array of transferable objects to transfer ownership of. The ownership of these objects is given to the destination side and they are no longer usable on the sending side.

### Return value

None (`undefined`).

Examples
--------

 In the following code block, you can see a new channel being created using the
 `MessageChannel()` constructor. When the
 IFrame has loaded, we pass `MessageChannel.port2` to the IFrame using
 `window.postMessage` along with a message. The iframe receives the message,
 and sends a message back on the `MessageChannel` using `postMessage()`.
 The `handleMessage` handler then responds to a message being sent back from the iframe using
 `onmessage`, putting it into a paragraph —
 `MessageChannel.port1` is listened to, to check when the message arrives.

```js
const channel = new MessageChannel();
const para = document.querySelector("p");

const ifr = document.querySelector("iframe");
const otherWindow = ifr.contentWindow;

ifr.addEventListener("load", iframeLoaded, false);

function iframeLoaded() {
  otherWindow.postMessage("Transferring message port", "\*", [channel.port2]);
}

channel.port1.onmessage = handleMessage;
function handleMessage(e) {
  para.innerHTML = e.data;
}

// in the iframe…

window.addEventListener("message", (event) => {
  const messagePort = event.ports?.[0];
  messagePort.postMessage("Hello from the iframe!");
});
```

For a full working example, see our channel messaging basic demo on GitHub (run it live too).

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

| Specification |
| --- |
| HTML Standard # dom-messageport-postmessage-dev |

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

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

See also
--------

* Using channel messaging


MessagePort: messageerror event - Web APIs

MessagePort: messageerror event
===============================

The **`messageerror`** event is fired on a `MessagePort` object when it receives a message that can't be deserialized.

This event is not cancellable and does not bubble.

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

Syntax
------

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

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

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

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

A `MessageEvent`. Inherits from `Event`.

Event

MessageEventEvent properties
----------------

*This interface also inherits properties from its parent, `Event`.*

`MessageEvent.data` Read only

The data sent by the message emitter.

`MessageEvent.origin` Read only

A string representing the origin of the message emitter.

`MessageEvent.lastEventId` Read only

A string representing a unique ID for the event.

`MessageEvent.source` Read only

A `MessageEventSource` (which can be a WindowProxy, `MessagePort`, or `ServiceWorker` object) representing the message emitter.

`MessageEvent.ports` Read only

An array of `MessagePort` objects representing the ports associated with the channel the message is being sent through (where appropriate, e.g. in channel messaging or when sending a message to a shared worker).

Examples
--------

Suppose a script creates a `MessageChannel` and sends one of the ports to a different browsing context, such as another `<iframe>`, using code like this:

```js
const channel = new MessageChannel();
const myPort = channel.port1;
const targetFrame = window.top.frames[1];
const targetOrigin = "https://example.org";

const messageControl = document.querySelector("#message");
const channelMessageButton = document.querySelector("#channel-message");

channelMessageButton.addEventListener("click", () => {
  myPort.postMessage(messageControl.value);
});

targetFrame.postMessage("init", targetOrigin, [channel.port2]);
```

The target can receive the port and start listening for messages and message errors on it using code like this:

```js
window.addEventListener("message", (event) => {
  const myPort = event.ports[0];

  myPort.addEventListener("message", (event) => {
    received.textContent = event.data;
  });

  myPort.addEventListener("messageerror", (event) => {
    console.error(event.data);
  });

  myPort.start();
});
```

Note that the listener must call `MessagePort.start()` before any messages will be delivered to this port. This is only needed when using the `addEventListener()` method: if the receiver uses `onmessage` instead, `start()` is called implicitly:

```js
window.addEventListener("message", (event) => {
  const myPort = event.ports[0];

  myPort.onmessage = (event) => {
    received.textContent = event.data;
  };

  myPort.onmessageerror = (event) => {
    console.error(event.data);
  };
});
```

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

| Specification |
| --- |
| HTML Standard # event-messageerror |
| HTML Standard # handler-messageport-onmessageerror |

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

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

See also
--------

* Related events: `message`.
* Using channel messaging


MessagePort: message event - Web APIs

MessagePort: message event
==========================

The **`message`** event is fired on a `MessagePort` object when a message arrives on that channel.

This event is not cancellable and does not bubble.

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

Syntax
------

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

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

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

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

A `MessageEvent`. Inherits from `Event`.

Event

MessageEventEvent properties
----------------

*This interface also inherits properties from its parent, `Event`.*

`MessageEvent.data` Read only

The data sent by the message emitter.

`MessageEvent.origin` Read only

A string representing the origin of the message emitter.

`MessageEvent.lastEventId` Read only

A string representing a unique ID for the event.

`MessageEvent.source` Read only

A `MessageEventSource` (which can be a WindowProxy, `MessagePort`, or `ServiceWorker` object) representing the message emitter.

`MessageEvent.ports` Read only

An array of `MessagePort` objects representing the ports associated with the channel the message is being sent through (where appropriate, e.g. in channel messaging or when sending a message to a shared worker).

Examples
--------

Suppose a script creates a `MessageChannel` and sends one of the ports to a different browsing context, such as another `<iframe>`, using code like this:

```js
const channel = new MessageChannel();
const myPort = channel.port1;
const targetFrame = window.top.frames[1];
const targetOrigin = "https://example.org";

const messageControl = document.querySelector("#message");
const channelMessageButton = document.querySelector("#channel-message");

channelMessageButton.addEventListener("click", () => {
  myPort.postMessage(messageControl.value);
});

targetFrame.postMessage("init", targetOrigin, [channel.port2]);
```

The target can receive the port and start listening for messages on it using code like this:

```js
window.addEventListener("message", (event) => {
  const myPort = event.ports[0];

  myPort.addEventListener("message", (event) => {
    received.textContent = event.data;
  });

  myPort.start();
});
```

Note that the listener must call `MessagePort.start()` before any messages will be delivered to this port. This is only needed when using the `addEventListener()` method: if the receiver uses `onmessage` instead, `start()` is called implicitly:

```js
window.addEventListener("message", (event) => {
  const myPort = event.ports[0];

  myPort.onmessage = (event) => {
    received.textContent = event.data;
  };
});
```

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

| Specification |
| --- |
| HTML Standard # event-message |
| HTML Standard # handler-messageport-onmessage |

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

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

See also
--------

* Related events: `messageerror`.
* Using channel messaging


MessagePort: start() method - Web APIs

MessagePort: start() method
===========================

 The **`start()`** method of the `MessagePort`
 interface starts the sending of messages queued on the port. This method is only needed
 when using `EventTarget.addEventListener`; it is implied when using
 `onmessage`.

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

Syntax
------

```js
start()
```

### Parameters

None.

### Return value

None (`undefined`).

Examples
--------

 In the following code block, you can see a `handleMessage` handler function,
 run when a message is sent back to this document using `onmessage`:

```js
channel.port1.onmessage = handleMessage;
function handleMessage(e) {
  para.innerHTML = e.data;
}
```

 Another option would be to do this using `EventTarget.addEventListener`,
 however, when this method is used, you need to explicitly call `start()` to
 begin the flow of messages to this document:

```js
channel.port1.addEventListener("message", handleMessage, false);
function handleMessage(e) {
  para.innerHTML = e.data;
  textInput.value = "";
}

channel.port1.start();
```

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

| Specification |
| --- |
| HTML Standard # dom-messageport-start-dev |

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

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

See also
--------

* Using channel messaging


ReadableStream: getReader() method - Web APIs

ReadableStream: getReader() method
==================================

 The **`getReader()`** method of the `ReadableStream` interface creates a reader and locks the stream to it.
 While the stream is locked, no other reader can be acquired until this one is released.

Syntax
------

```js
getReader()
getReader(options)
```

### Parameters

`options` Optional

An object containing the following properties:

`mode` Optional

 An property that specifies the type of reader to create.
 Values can be:

* `"byob"`, which results in a `ReadableStreamBYOBReader` being created that can read readable byte streams (streams that support zero-copy transfer from an underlying byte source to the reader when internal stream buffers are empty).
* `undefined` (or not specified at all — this is the default), which results in a `ReadableStreamDefaultReader` being created that can read individual chunks from a stream.

### Return value

A `ReadableStreamDefaultReader` or `ReadableStreamBYOBReader` object instance, depending on the `mode` value.

### Exceptions

`RangeError`

Thrown if the provided mode value is not `"byob"` or `undefined`.

`TypeError`

 Thrown if the stream you are trying to create a reader for is already locked, or not a `ReadableStream`.
 This is also thrown if a BYOB reader is requested and the stream controller is not a `ReadableByteStreamController` (the stream was not constructed as an underlying source with `type="bytes"`).

Examples
--------

 In the following simple example, a previously-created custom `ReadableStream` is read using a `ReadableStreamDefaultReader` created using `getReader()`.
 (see our Simple random stream example for the full code).
 Each chunk is read sequentially and output to the UI, until the stream has finished being read, at which point we return out of the recursive function and print the entire stream to another part of the UI.

```js
function fetchStream() {
  const reader = stream.getReader();
  let charsReceived = 0;

  // read() returns a promise that resolves
  // when a value has been received
  reader.read().then(function processText({ done, value }) {
    // Result objects contain two properties:
    // done - true if the stream has already given you all its data.
    // value - some data. Always undefined when done is true.
    if (done) {
      console.log("Stream complete");
      para.textContent = value;
      return;
    }

    // value for fetch streams is a Uint8Array
    charsReceived += value.length;
    const chunk = value;
    let listItem = document.createElement("li");
    listItem.textContent = `Received ${charsReceived} characters so far. Current chunk = ${chunk}`;
    list2.appendChild(listItem);

    result += chunk;

    // Read some more, and call this function again
    return reader.read().then(processText);
  });
}
```

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

| Specification |
| --- |
| Streams Standard # ref-for-rs-get-reader⑤ |

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

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

See also
--------

* `ReadableStream()` constructor
* `ReadableStreamDefaultReader`
* `ReadableStreamBYOBReader`
* Using readable streams
* Using readable byte stream