GamepadEvent - Web APIs

GamepadEvent
============

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

The GamepadEvent interface of the Gamepad API contains references to gamepads connected to the system, which is what the gamepad events `gamepadconnected` and `gamepaddisconnected` are fired in response to.

Event

GamepadEventConstructor
-----------

`GamepadEvent()`

Returns a new `GamepadEvent` object.

Instance properties
-------------------

`GamepadEvent.gamepad` Read only

Returns a `Gamepad` object, providing access to the associated gamepad data for the event fired.

Examples
--------

The gamepad property being called on a fired `gamepadconnected` event.

```js
window.addEventListener("gamepadconnected", (e) => {
  console.log(
    "Gamepad connected at index %d: %s. %d buttons, %d axes.",
    e.gamepad.index,
    e.gamepad.id,
    e.gamepad.buttons.length,
    e.gamepad.axes.length,
  );
});
```

And on a `gamepaddisconnected` event.

```js
window.addEventListener("gamepaddisconnected", (e) => {
  console.log(
    "Gamepad disconnected from index %d: %s",
    e.gamepad.index,
    e.gamepad.id,
  );
});
```

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

| Specification |
| --- |
| Gamepad # gamepadevent-interface |

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

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

See also
--------

Using the Gamepad API


NavigationDestination - Web APIs

NavigationDestination
=====================

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

The **`NavigationDestination`** interface of the Navigation API represents the destination being navigated to in the current navigation.

It is accessed via the `NavigateEvent.destination` property.

Instance properties
-------------------

`id` Read only
Experimental

Returns the `id` value of the destination `NavigationHistoryEntry` if the `NavigateEvent.navigationType` is `traverse`, or an empty string otherwise.

`index` Read only
Experimental

Returns the `index` value of the destination `NavigationHistoryEntry` if the `NavigateEvent.navigationType` is `traverse`, or `-1` otherwise.

`key` Read only
Experimental

Returns the `key` value of the destination `NavigationHistoryEntry` if the `NavigateEvent.navigationType` is `traverse`, or an empty string otherwise.

`sameDocument` Read only
Experimental

Returns `true` if the navigation is to the same `document` as the current `Document` value, or `false` otherwise.

`url` Read only
Experimental

Returns the URL being navigated to.

Instance methods
----------------

`getState()`
Experimental

Returns a clone of the available state associated with the destination `NavigationHistoryEntry`, or navigation operation (e.g. `navigate()`) as appropriate.

Examples
--------

```js
navigation.addEventListener("navigate", (event) => {
  // Exit early if this navigation shouldn't be intercepted,
  // e.g. if the navigation is cross-origin, or a download request
  if (shouldNotIntercept(event)) {
    return;
  }

  // Returns a URL() object constructed from the
  // NavigationDestination.url value
  const url = new URL(event.destination.url);

  if (url.pathname.startsWith("/articles/")) {
    event.intercept({
      async handler() {
        // The URL has already changed, so show a placeholder while
        // fetching the new content, such as a spinner or loading page
        renderArticlePagePlaceholder();

        // Fetch the new content and display when ready
        const articleContent = await getArticleContent(url.pathname);
        renderArticlePage(articleContent);
      },
    });
  }
});
```

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

| Specification |
| --- |
| HTML Standard # the-navigationdestination-interface |

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

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

See also
--------

* Modern client-side routing: the Navigation API
* Navigation API explainer
* Domenic Denicola's Navigation API live demo


HTMLSlotElement - Web APIs

HTMLSlotElement
===============

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.

* Learn more
* See full compatibility
* Report feedback
The **`HTMLSlotElement`** interface of the Shadow DOM API enables access to the name and assigned nodes of an HTML `<slot>` element.

EventTarget

Node

Element

HTMLElement

HTMLSlotElementInstance properties
-------------------

*Also inherits properties from its parent interface, `HTMLElement`.*

`HTMLSlotElement.name`

A string used to get and set the slot's name.

Instance methods
----------------

*Also inherits methods from its parent interface, `HTMLElement`.*

`HTMLSlotElement.assign()`

Sets the manually assigned nodes for this slot to the given nodes.

`HTMLSlotElement.assignedNodes()`

Returns a sequence of the nodes assigned to this slot. If the `flatten` option is set to `true`, it returns a sequence of both the nodes assigned to this slot, and the nodes assigned to any other slots that are descendants of this slot. If no assigned nodes are found, it returns the slot's fallback content.

`HTMLSlotElement.assignedElements()`

Returns a sequence of the elements assigned to this slot (and no other nodes). If the `flatten` option is set to `true`, it returns a sequence of both the elements assigned to this slot, and the elements assigned to any other slots that are descendants of this slot. If no assigned elements are found, it returns the slot's fallback content.

Events
------

*Also inherits events from its parent interface, `HTMLElement`.*

Listen to these events using `addEventListener()` or by assigning an event listener to the `oneventname` property of this interface.

`slotchange`

Fired on an `HTMLSlotElement` instance (`<slot>` element) when the node(s) contained in that slot change.

Examples
--------

The following snippet is taken from our slotchange example (see it live also).

```js
let slots = this.shadowRoot.querySelectorAll("slot");
slots[1].addEventListener("slotchange", (e) => {
  let nodes = slots[1].assignedNodes();
  console.log(
    `Element in Slot "${slots[1].name}" changed to "${nodes[0].outerHTML}".`,
  );
});
```

Here we grab references to all the slots, then add a slotchange event listener to the 2nd slot in the template — which is the one that keeps having its contents changed in the example.

Every time the element inserted in the slot changes, we log a report to the console saying which slot has changed, and what the new node inside the slot is.

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

| Specification |
| --- |
| HTML Standard # htmlslotelement |

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

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


WorkletSharedStorage - Web APIs

WorkletSharedStorage
====================

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

The **`WorkletSharedStorage`** interface of the Shared Storage API represents the shared storage for a particular origin within a worklet context.

`WorkletSharedStorage` is accessed via `SharedStorageWorkletGlobalScope.sharedStorage`.

SharedStorage

WorkletSharedStorageInstance properties
-------------------

`context`
Experimental

Non-standard

Contains contextual data passed into the shared storage worklet from the associated browsing context via the `FencedFrameConfig.setSharedStorageContext()` method.

Instance methods
----------------

*`WorkletSharedStorage` inherits properties from its parent interface, `SharedStorage`.*

`get()`
Experimental

Retrieves a value from the shared storage.

`length()`
Experimental

Returns the number of entries currently stored in the shared storage for the current origin.

`remainingBudget()`
Experimental

Returns the remaining navigation budget for the current origin.

`WorkletSharedStorage` also includes the following methods because it has an async iterator defined on it:

`entries()`
Experimental

Returns a new async iterator for the key-value pairs of a `WorkletSharedStorage` object instance's enumerable properties.

`keys()`
Experimental

Returns a new async iterator containing the keys for each item in a `WorkletSharedStorage` object instance.

`WorkletSharedStorage[@@asyncIterator]()`
Experimental

Returns the `entries()` function by default.

Examples
--------

### Passing contextual data via `setSharedStorageContext()`

You can use the Private Aggregation API to create reports that combine event-level data inside fenced frames with contextual data from the embedding document. `setSharedStorageContext()` can be used to pass contextual data from the embedder to shared storage worklets initiated by the Protected Audience API.

In this example, we store data from both the embedding page and the fenced frame using shared storage.

On the embedding page, we set a mock event ID as the shared storage context using `setSharedStorageContext()`:

```js
const frameConfig = await navigator.runAdAuction({ resolveToConfig: true });

// Data from the embedder that you want to pass to the shared storage worklet
frameConfig.setSharedStorageContext("some-event-id");

const frame = document.createElement("fencedframe");
frame.config = frameConfig;
```

Within the fenced frame, after adding the worklet module with `window.sharedStorage.worklet.addModule()`, we send the event-level data into the shared storage worklet module using `window.sharedStorage.run()` (this is unrelated to the contextual data from the embedding document):

```js
const frameData = {
  // Data available only inside the fenced frame
};

await window.sharedStorage.worklet.addModule("reporting-worklet.js");

await window.sharedStorage.run("send-report", {
  data: {
    frameData,
  },
});
```

In the `reporting-worklet.js` worklet, we read the embedding document's event ID from `sharedStorage.context` and the frame's event-level data from the data object. We then report them through Private Aggregation:

```js
class ReportingOperation {
  convertEventIdToBucket(eventId) { ... }
  convertEventPayloadToValue(info) { ... }

  async run(data) {
    // Data from the embedder
    const eventId = sharedStorage.context;

    // Data from the fenced frame
    const eventPayload = data.frameData;

    privateAggregation.sendHistogramReport({
      bucket: convertEventIdToBucket(eventId),
      value: convertEventPayloadToValue(eventPayload)
    });
  }
}

register('send-report', ReportingOperation);
```

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

| Specification |
| --- |
| Shared Storage API # workletsharedstorage |

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

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

See also
--------

* Shared Storage API


Content Index API - Web APIs

Content Index API
=================

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

The **Content Index API** allows developers to register their offline enabled content with the browser.

Concepts and usage
------------------

As it stands, offline web content is not easily discoverable by users. Content indexing allows developers to tell the browser about their specific offline content. This allows users to discover and view what is available, whilst giving developers the ability to add and manage this content. Examples could be a news website prefetching the latest articles in the background, or a content streaming app registering downloaded content.

The Content Index API is an extension to service workers, which allows developers to add URLs and metadata of already cached pages, under the scope of the current service worker. The browser can then use these entries to display offline reading to a user. As a developer you can also display these entries within your application.

Indexed entries do not automatically expire. It's good practice to present an interface for clearing out entries, or periodically remove older entries.

**Note:** The API supports indexing URLs corresponding to HTML documents. A URL for a cached media file, for example, can't be indexed directly. Instead, you need to provide a URL for a page that displays media, and which works offline.

Interfaces
----------

`ContentIndex`

The **`ContentIndex`** interface provides functionality to register content available offline.

`ContentIndexEvent`

The **`ContentIndexEvent`** interface of the `Content Index API` defines the object used to represent the `contentdelete` event.

Service worker additions
------------------------

The following additions to the `ServiceWorker` have been specified in the Content Index API spec to provide an entry point for using content indexing.

`ServiceWorkerRegistration.index` Read only

Returns a reference to the `ContentIndex` interface for indexing cached pages.

`contentdelete` event
Experimental

An event fired when content is removed by the user agent.

Examples
--------

All the following examples assume a service worker has been registered. For more information see the Service Worker API.

### Feature detection and interface access

Here we get a reference to the `ServiceWorkerRegistration`, then check for the `index` property, which gives us access to the content index interface.

```js
// reference registration
const registration = await navigator.serviceWorker.ready;

// feature detection
if ("index" in registration) {
  // Content Index API functionality
  const contentIndex = registration.index;
}
```

### Adding to the content index

Here we're declaring an item in the correct format and creating an asynchronous function which uses the `add()` method to register it with the `content index`.

```js
// our content
const item = {
  id: "post-1",
  url: "/posts/amet.html",
  title: "Amet consectetur adipisicing",
  description:
    "Repellat et quia iste possimus ducimus aliquid a aut eaque nostrum.",
  icons: [
    {
      src: "/media/dark.png",
      sizes: "128x128",
      type: "image/png",
    },
  ],
  category: "article",
};

// our asynchronous function to add indexed content
async function registerContent(data) {
  const registration = await navigator.serviceWorker.ready;

  // feature detect Content Index
  if (!registration.index) {
    return;
  }

  // register content
  try {
    await registration.index.add(data);
  } catch (e) {
    console.log("Failed to register content: ", e.message);
  }
}
```

### Retrieving items within the current index

The below example shows an asynchronous function that retrieves items within the content index and iterates over each entry, building a list for the interface.

```js
async function createReadingList() {
  // access our service worker registration
  const registration = await navigator.serviceWorker.ready;

  // get our index entries
  const entries = await registration.index.getAll();

  // create a containing element
  const readingListElem = document.createElement("div");

  // test for entries
  if (!Array.length) {
    // if there are no entries, display a message
    const message = document.createElement("p");
    message.innerText =
      "You currently have no articles saved for offline reading.";

    readingListElem.append(message);
  } else {
    // if entries are present, display in a list of links to the content
    const listElem = document.createElement("ul");

    for (const entry of entries) {
      const listItem = document.createElement("li");

      const anchorElem = document.createElement("a");
      anchorElem.innerText = entry.title;
      anchorElem.setAttribute("href", entry.url);

      listElem.append(listItem);
    }

    readingListElem.append(listElem);
  }
}
```

### Unregistering indexed content

Below is an asynchronous function, that removes an item from the content index.

```js
async function unregisterContent(article) {
  // reference registration
  const registration = await navigator.serviceWorker.ready;

  // feature detect Content Index
  if (!registration.index) return;

  // unregister content from index
  await registration.index.delete(article.id);
}
```

All the above methods are available within the scope of the service worker. They are accessible from the `WorkerGlobalScope.self` property:

```js
// service worker script

self.registration.index.add(item);

self.registration.index.delete(item.id);

const contentIndexItems = self.registration.index.getAll();
```

### The contentdelete event

When an item is removed from the user agent interface, a `contentdelete` event is received by the service worker.

```js
self.addEventListener("contentdelete", (event) => {
  console.log(event.id);

  // logs content index id, which can then be used to determine what content to delete from your cache
});
```

The `contentdelete` event is only fired when the deletion happens due to interaction with the browser's built-in user interface. It is not fired when the `ContentIndex.delete()` method is called.

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

| Specification |
| --- |
| Content Index # content-index |

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

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

See also
--------

* An introductory article on the Content Index API
* An app which uses the Content Index API to list and remove 'save for later' content
* Service Worker API, along with information about Cache and CacheStorage


Cookie Store API - Web APIs

Cookie Store API
================

**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 **Cookie Store API** is an asynchronous API for managing cookies, available in windows and also service workers.

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

Concepts and Usage
------------------

The existing method of getting and setting cookies involves working with `document.cookie` as a string of key/value pairs. In addition to this being cumbersome and error prone, it also has a host of issues in the context of modern web development.

The `document.cookie` interface is synchronous, single-threaded, and blocking. When writing a cookie you must wait for the browser to update the string of all cookies. In addition, the reliance on `document` means that cookies cannot be accessed by service workers which cannot access the `document` object.

The *Cookie Store API* provides an updated method of managing cookies. It is asynchronous and promise-based, therefore does not block the event loop. It does not rely on `document` and so is available to service workers. The methods for getting and setting cookies also provide more feedback by way of error messages. This means that web developers do not have to set then immediately read back a cookie to check that setting was successful.

Interfaces
----------

`CookieStore`
Experimental

The `CookieStore` interface enables getting and setting cookies.

`CookieStoreManager`
Experimental

The `CookieStoreManager` interface provides a service worker registration to enable service workers to subscribe to cookie change events.

`CookieChangeEvent`
Experimental

A `CookieChangeEvent` named `change` is dispatched against `CookieStore` objects in `Window` contexts when any script-visible cookies changes occur.

`ExtendableCookieChangeEvent`

An `ExtendableCookieChangeEvent` named `cookiechange` is dispatched in `ServiceWorkerGlobalScope` contexts when any script-visible cookie changes occur that match the service worker's cookie change subscription list.

### Extensions to other interfaces

`ServiceWorkerGlobalScope.cookieStore` Read only
Experimental

Returns a reference to the `CookieStore` object associated with the service worker.

`ServiceWorkerRegistration.cookies` Read only
Experimental

Returns a reference to the `CookieStoreManager` interface, which enables a web app to subscribe to and unsubscribe from cookie change events.

`Window.cookieStore` Read only
Experimental

Returns a reference to the `CookieStore` object for the current document context.

`cookiechange` event
Experimental

Fired when any cookie changes have occurred which match the service worker's cookie change subscription list.

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

| Specification |
| --- |
| Cookie Store API  |

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

### api.CookieStore

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

### api.CookieStoreManager

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

See also
--------

* Service Worker API


ByteLengthQueuingStrategy - Web APIs

ByteLengthQueuingStrategy
=========================

The **`ByteLengthQueuingStrategy`** interface of the Streams API provides a built-in byte length queuing strategy that can be used when constructing streams.

Constructor
-----------

`ByteLengthQueuingStrategy()`

Creates a new `ByteLengthQueuingStrategy` object instance.

Instance properties
-------------------

`ByteLengthQueuingStrategy.highWaterMark` Read only

The total number of bytes that can be contained in the internal queue before backpressure is applied.

Instance methods
----------------

`ByteLengthQueuingStrategy.size()`

Returns the given chunk's `byteLength` property.

Examples
--------

```js
const queueingStrategy = new ByteLengthQueuingStrategy({ highWaterMark: 1024 });

const readableStream = new ReadableStream(
  {
    start(controller) {
      // …
    },
    pull(controller) {
      // …
    },
    cancel(err) {
      console.log("stream error:", err);
    },
  },
  queueingStrategy,
);

const size = queueingStrategy.size(chunk);
```

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

| Specification |
| --- |
| Streams Standard # blqs-class |

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

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

See also
--------

* Streams API
* Internal queues and queuing strategies
* `ByteLengthQueuingStrategy()` constructor


RTCEncodedAudioFrame - Web APIs

RTCEncodedAudioFrame
====================

The **`RTCEncodedAudioFrame`** of the WebRTC API represents an encoded audio frame in the WebRTC receiver or sender pipeline, which may be modified using a WebRTC Encoded Transform.

 The interface provides methods and properties to get metadata about the frame, allowing its format and order in the sequence of frames to be determined.
 The `data` property gives access to the encoded frame data as a buffer, which might be encrypted, or otherwise modified by a transform.

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

Instance properties
-------------------

`RTCEncodedAudioFrame.timestamp` Read only

Returns the timestamp at which sampling of the frame started.

`RTCEncodedAudioFrame.data`

Return a buffer containing the encoded frame data.

Instance methods
----------------

`RTCEncodedAudioFrame.getMetadata()`

Returns the metadata associated with the frame.

Examples
--------

This code snippet shows a handler for the `rtctransform` event in a `Worker` that implements a `TransformStream`, and pipes encoded frames through it from the `event.transformer.readable` to `event.transformer.writable` (`event.transformer` is a `RTCRtpScriptTransformer`, the worker-side counterpart of `RTCRtpScriptTransform`).

 If the tranformer is inserted into an audio stream, the `transform()` method is called with a `RTCEncodedAudioFrame` whenever a new frame is enqueued on `event.transformer.readable`.
 The `transform()` method shows how this might be read, modified using a fictional encryption function, and then enqueued on the controller (this ultimately pipes it through to the `event.transformer.writable`, and then back into the WebRTC pipline).

```js
addEventListener("rtctransform", (event) => {
  const async transform = new TransformStream({
    async transform(encodedFrame, controller) {
      // Reconstruct the original frame.
      const view = new DataView(encodedFrame.data);

      // Construct a new buffer
      const newData = new ArrayBuffer(encodedFrame.data.byteLength);
      const newView = new DataView(newData);

      //Encrypt frame bytes using the encryptFunction() method (not shown)
      for (let i = 0; i < encodedFrame.data.byteLength; ++i) {
        const encryptedByte = encryptFunction(~view.getInt8(i));
        newView.setInt8(i, encryptedByte);
      }

      encodedFrame.data = newData;
      controller.enqueue(encodedFrame);
    },
  });
  event.transformer.readable
    .pipeThrough(transform)
    .pipeTo(event.transformer.writable);
});
```

Note that more complete examples are provided in Using WebRTC Encoded Transforms.

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

| Specification |
| --- |
| WebRTC Encoded Transform # ref-for-rtcencodedaudioframe%E2%91%A1 |

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

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

See also
--------

* Using WebRTC Encoded Transforms
* `TransformStream`
* `RTCRtpScriptTransformer`
* `RTCEncodedVideoFrame`


Intersection Observer API - Web APIs

Intersection Observer API
=========================

The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.

Historically, detecting visibility of an element, or the relative visibility of two elements in relation to each other, has been a difficult task for which solutions have been unreliable and prone to causing the browser and the sites the user is accessing to become sluggish. As the web has matured, the need for this kind of information has grown. Intersection information is needed for many reasons, such as:

* Lazy-loading of images or other content as a page is scrolled.
* Implementing "infinite scrolling" websites, where more and more content is loaded and rendered as you scroll, so that the user doesn't have to flip through pages.
* Reporting of visibility of advertisements in order to calculate ad revenues.
* Deciding whether or not to perform tasks or animation processes based on whether or not the user will see the result.

Implementing intersection detection in the past involved event handlers and loops calling methods like `Element.getBoundingClientRect()` to build up the needed information for every element affected. Since all this code runs on the main thread, even one of these can cause performance problems. When a site is loaded with these tests, things can get downright ugly.

Consider a web page that uses infinite scrolling. It uses a vendor-provided library to manage the advertisements placed periodically throughout the page, has animated graphics here and there, and uses a custom library that draws notification boxes and the like. Each of these has its own intersection detection routines, all running on the main thread. The author of the website may not even realize this is happening, since they may know very little about the inner workings of the two libraries they are using. As the user scrolls the page, these intersection detection routines are firing constantly during the scroll handling code, resulting in an experience that leaves the user frustrated with the browser, the website, and their computer.

The Intersection Observer API lets code register a callback function that is executed whenever a particular element enters or exits an intersection with another element (or the viewport), or when the intersection between two elements changes by a specified amount. This way, sites no longer need to do anything on the main thread to watch for this kind of element intersection, and the browser is free to optimize the management of intersections as it sees fit.

One thing the Intersection Observer API can't tell you: the exact number of pixels that overlap or specifically which ones they are; however, it covers the much more common use case of "If they intersect by somewhere around *N*%, I need to do something."

Intersection observer concepts and usage
----------------------------------------

The Intersection Observer API allows you to configure a callback that is called when either of these circumstances occur:

* A **target** element intersects either the device's viewport or a specified element. That specified element is called the **root element** or **root** for the purposes of the Intersection Observer API.
* The first time the observer is initially asked to watch a target element.

Typically, you'll want to watch for intersection changes with regard to the target element's closest scrollable ancestor, or, if the target element isn't a descendant of a scrollable element, the device's viewport. To watch for intersection relative to the device's viewport, specify `null` for the `root` option. Keep reading for a more detailed explanation about intersection observer options.

Whether you're using the viewport or some other element as the root, the API works the same way, executing a callback function you provide whenever the visibility of the target element changes so that it crosses desired amounts of intersection with the root.

The degree of intersection between the target element and its root is the **intersection ratio**. This is a representation of the percentage of the target element which is visible as a value between 0.0 and 1.0.

### Creating an intersection observer

Create the intersection observer by calling its constructor and passing it a callback function to be run whenever a threshold is crossed in one direction or the other:

```js
let options = {
  root: document.querySelector("#scrollArea"),
  rootMargin: "0px",
  threshold: 1.0,
};

let observer = new IntersectionObserver(callback, options);
```

A threshold of 1.0 means that when 100% of the target is visible within the element specified by the `root` option, the callback is invoked.

#### Intersection observer options

The `options` object passed into the `IntersectionObserver()` constructor let you control the circumstances under which the observer's callback is invoked. It has the following fields:

`root`

The element that is used as the viewport for checking visibility of the target. Must be the ancestor of the target. Defaults to the browser viewport if not specified or if `null`.

`rootMargin`

Margin around the root. Can have values similar to the CSS `margin` property, e.g. `"10px 20px 30px 40px"` (top, right, bottom, left). The values can be percentages. This set of values serves to grow or shrink each side of the root element's bounding box before computing intersections. Defaults to all zeros.

`threshold`

Either a single number or an array of numbers which indicate at what percentage of the target's visibility the observer's callback should be executed. If you only want to detect when visibility passes the 50% mark, you can use a value of 0.5. If you want the callback to run every time visibility passes another 25%, you would specify the array [0, 0.25, 0.5, 0.75, 1]. The default is 0 (meaning as soon as even one pixel is visible, the callback will be run). A value of 1.0 means that the threshold isn't considered passed until every pixel is visible.

#### Targeting an element to be observed

Once you have created the observer, you need to give it a target element to watch:

```js
let target = document.querySelector("#listItem");
observer.observe(target);

// the callback we set up for the observer will be executed now for the first time
// it waits until we assign a target to our observer (even if the target is currently not visible)
```

Whenever the target meets a threshold specified for the `IntersectionObserver`, the callback is invoked. The callback receives a list of `IntersectionObserverEntry` objects and the observer:

```js
let callback = (entries, observer) => {
  entries.forEach((entry) => {
    // Each entry describes an intersection change for one observed
    // target element:
    // entry.boundingClientRect
    // entry.intersectionRatio
    // entry.intersectionRect
    // entry.isIntersecting
    // entry.rootBounds
    // entry.target
    // entry.time
  });
};
```

The list of entries received by the callback includes one entry for each target which reported a change in its intersection status. Check the value of the `isIntersecting` property to see if the entry represents an element that currently intersects with the root.

Be aware that your callback is executed on the main thread. It should operate as quickly as possible; if anything time-consuming needs to be done, use `Window.requestIdleCallback()`.

Also, note that if you specified the `root` option, the target must be a descendant of the root element.

### How intersection is calculated

All areas considered by the Intersection Observer API are rectangles; elements which are irregularly shaped are considered as occupying the smallest rectangle which encloses all of the element's parts. Similarly, if the visible portion of an element is not rectangular, the element's intersection rectangle is considered to be the smallest rectangle that contains all the visible portions of the element.

It's useful to understand a bit about how the various properties provided by `IntersectionObserverEntry` describe an intersection.

#### The intersection root and root margin

Before we can track the intersection of an element with a container, we need to know what that container is. That container is the **intersection root**, or **root element**. This can be either a specific element in the document which is an ancestor of the element to be observed, or `null` to use the document's viewport as the container.

The ***root intersection rectangle*** is the rectangle used to check against the target or targets. This rectangle is determined like this:

* If the intersection root is the implicit root (that is, the top-level `Document`), the root intersection rectangle is the viewport's rectangle.
* If the intersection root has an overflow clip, the root intersection rectangle is the root element's content area.
* Otherwise, the root intersection rectangle is the intersection root's bounding client rectangle (as returned by calling `getBoundingClientRect()` on it).

The root intersection rectangle can be adjusted further by setting the **root margin**, `rootMargin`, when creating the `IntersectionObserver`. The values in `rootMargin` define offsets added to each side of the intersection root's bounding box to create the final intersection root bounds (which are disclosed in `IntersectionObserverEntry.rootBounds` when the callback is executed).

#### Thresholds

Rather than reporting every infinitesimal change in how much a target element is visible, the Intersection Observer API uses **thresholds**. When you create an observer, you can provide one or more numeric values representing percentages of the target element which are visible. Then, the API only reports changes to visibility which cross these thresholds.

For example, if you want to be informed every time a target's visibility passes backward or forward through each 25% mark, you would specify the array [0, 0.25, 0.5, 0.75, 1] as the list of thresholds when creating the observer.

When the callback is invoked, it receives a list of `IntersectionObserverEntry` objects, one for each observed target which has had the degree to which it intersects the root change such that the amount exposed crosses over one of the thresholds, in either direction.

You can see if the target *currently* intersects the root by looking at the entry's `isIntersecting` property; if its value is `true`, the target is at least partially intersecting the root element or document. This lets you determine whether the entry represents a transition from the elements intersecting to no longer intersecting or a transition from not intersecting to intersecting.

Note that it's possible to have a zero intersection rectangle, which can happen if the intersection is exactly along the boundary between the two or the area of `boundingClientRect` is zero. This state of the target and root sharing a boundary line is not considered enough to be considered transitioning into an intersecting state.

To get a feeling for how thresholds work, try scrolling the box below around. Each colored box within it displays the percentage of itself that's visible in all four of its corners, so you can see these ratios change over time as you scroll the container. Each box has a different set of thresholds:

* The first box has a threshold for each percentage point of visibility; that is, the `IntersectionObserver.thresholds` array is `[0.00, 0.01, 0.02, /*…,*/ 0.99, 1.00]`.
* The second box has a single threshold, at the 50% mark.
* The third box has thresholds every 10% of visibility (0%, 10%, 20%, etc.).
* The last box has thresholds each 25%.
```

<template id="boxTemplate">
  <div class="sampleBox">
    <div class="label topLeft"></div>
    <div class="label topRight"></div>
    <div class="label bottomLeft"></div>
    <div class="label bottomRight"></div>
  </div>
</template>

<main>
  <div class="contents">
    <div class="wrapper"></div>
  </div>
</main>
```

```
.contents {
  position: absolute;
  width: 700px;
  height: 1725px;
}

.wrapper {
  position: relative;
  top: 600px;
}

.sampleBox {
  position: relative;
  left: 175px;
  width: 150px;
  background-color: rgb(245 170 140);
  border: 2px solid rgb(201 126 17);
  padding: 4px;
  margin-bottom: 6px;
}

#box1 {
  height: 200px;
}

#box2 {
  height: 75px;
}

#box3 {
  height: 150px;
}

#box4 {
  height: 100px;
}

.label {
  font:
    14px "Open Sans",
    "Arial",
    sans-serif;
  position: absolute;
  margin: 0;
  background-color: rgb(255 255 255 / 70%);
  border: 1px solid rgb(0 0 0 / 70%);
  width: 3em;
  height: 18px;
  padding: 2px;
  text-align: center;
}

.topLeft {
  left: 2px;
  top: 2px;
}

.topRight {
  right: 2px;
  top: 2px;
}

.bottomLeft {
  bottom: 2px;
  left: 2px;
}

.bottomRight {
  bottom: 2px;
  right: 2px;
}
```

```
let observers = [];

startup = () => {
  let wrapper = document.querySelector(".wrapper");

  // Options for the observers

  let observerOptions = {
    root: null,
    rootMargin: "0px",
    threshold: [],
  };

  // An array of threshold sets for each of the boxes. The
  // first box's thresholds are set programmatically
  // since there will be so many of them (for each percentage
  // point).

  let thresholdSets = [
    [],
    [0.5],
    [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
    [0, 0.25, 0.5, 0.75, 1.0],
  ];

  for (let i = 0; i <= 1.0; i += 0.01) {
    thresholdSets[0].push(i);
  }

  // Add each box, creating a new observer for each

  for (let i = 0; i < 4; i++) {
    let template = document
      .querySelector("#boxTemplate")
      .content.cloneNode(true);
    let boxID = `box${i + 1}`;
    template.querySelector(".sampleBox").id = boxID;
    wrapper.appendChild(document.importNode(template, true));

    // Set up the observer for this box

    observerOptions.threshold = thresholdSets[i];
    observers[i] = new IntersectionObserver(
      intersectionCallback,
      observerOptions,
    );
    observers[i].observe(document.querySelector(`#${boxID}`));
  }

  // Scroll to the starting position

  document.scrollingElement.scrollTop =
    wrapper.firstElementChild.getBoundingClientRect().top + window.scrollY;
  document.scrollingElement.scrollLeft = 750;
};

intersectionCallback = (entries) => {
  entries.forEach((entry) => {
    let box = entry.target;
    let visiblePct = `${Math.floor(entry.intersectionRatio \* 100)}%`;

    box.querySelector(".topLeft").innerHTML = visiblePct;
    box.querySelector(".topRight").innerHTML = visiblePct;
    box.querySelector(".bottomLeft").innerHTML = visiblePct;
    box.querySelector(".bottomRight").innerHTML = visiblePct;
  });
};

startup();
```

#### Clipping and the intersection rectangle

The browser computes the final intersection rectangle as follows; this is all done for you, but it can be helpful to understand these steps in order to better grasp exactly when intersections will occur.

1. The target element's bounding rectangle (that is, the smallest rectangle that fully encloses the bounding boxes of every component that makes up the element) is obtained by calling `getBoundingClientRect()` on the target. This is the largest the intersection rectangle may be. The remaining steps will remove any portions that don't intersect.
2. Starting at the target's immediate parent block and moving outward, each containing block's clipping (if any) is applied to the intersection rectangle. A block's clipping is determined based on the intersection of the two blocks and the clipping mode (if any) specified by the `overflow` property. Setting `overflow` to anything but `visible` causes clipping to occur.
3. If one of the containing elements is the root of a nested browsing context (such as the document contained in an `<iframe>`), the intersection rectangle is clipped to the containing context's viewport, and recursion upward through the containers continues with the container's containing block. So if the top level of an `<iframe>` is reached, the intersection rectangle is clipped to the frame's viewport, then the frame's parent element is the next block recursed through toward the intersection root.
4. When recursion upward reaches the intersection root, the resulting rectangle is mapped to the intersection root's coordinate space.
5. The resulting rectangle is then updated by intersecting it with the root intersection rectangle.
6. This rectangle is, finally, mapped to the coordinate space of the target's `document`.
### Intersection change callbacks

When the amount of a target element which is visible within the root element crosses one of the visibility thresholds, the `IntersectionObserver` object's callback is executed. The callback receives as input an array of all of `IntersectionObserverEntry` objects, one for each threshold which was crossed, and a reference to the `IntersectionObserver` object itself.

Each entry in the list of thresholds is an `IntersectionObserverEntry` object describing one threshold that was crossed; that is, each entry describes how much of a given element is intersecting with the root element, whether or not the element is considered to be intersecting or not, and the direction in which the transition occurred.

The code snippet below shows a callback which keeps a counter of how many times elements transition from not intersecting the root to intersecting by at least 75%. For a threshold value of 0.0 (default) the callback is called approximately upon transition of the boolean value of `isIntersecting`. The snippet thus first checks that the transition is a positive one, then determines whether `intersectionRatio` is above 75%, in which case it increments the counter.

```js
const intersectionCallback = (entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      let elem = entry.target;

      if (entry.intersectionRatio >= 0.75) {
        intersectionCounter++;
      }
    }
  });
};
```

Interfaces
----------

`IntersectionObserver`

The primary interface for the Intersection Observer API. Provides methods for creating and managing an observer which can watch any number of target elements for the same intersection configuration. Each observer can asynchronously observe changes in the intersection between one or more target elements and a shared ancestor element or with their top-level `Document`'s viewport. The ancestor or viewport is referred to as the **root**.

`IntersectionObserverEntry`

Describes the intersection between the target element and its root container at a specific moment of transition. Objects of this type can only be obtained in two ways: as an input to your `IntersectionObserver` callback, or by calling `IntersectionObserver.takeRecords()`.

A simple example
----------------

This simple example causes a target element to change its color and transparency as it becomes more or less visible. At Timing element visibility with the Intersection Observer API, you can find a more extensive example showing how to time how long a set of elements (such as ads) are visible to the user and to react to that information by recording statistics or by updating elements.

### HTML

The HTML for this example is very short, with a primary element which is the box that we'll be targeting (with the creative ID `"box"`) and some contents within the box.

```html
<div id="box">
  <div class="vertical">Welcome to <strong>The Box!</strong></div>
</div>
```

### CSS

The CSS isn't terribly important for the purposes of this example; it lays out the element and establishes that the `background-color` and `border` attributes can participate in CSS transitions, which we'll use to affect the changes to the element as it becomes more or less obscured.

```css
#box {
  background-color: rgb(40 40 190 / 100%);
  border: 4px solid rgb(20 20 120);
  transition:
    background-color 1s,
    border 1s;
  width: 350px;
  height: 350px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.vertical {
  color: white;
  font: 32px "Arial";
}

.extra {
  width: 350px;
  height: 350px;
  margin-top: 10px;
  border: 4px solid rgb(20 20 120);
  text-align: center;
  padding: 20px;
}
```

### JavaScript

Finally, let's take a look at the JavaScript code that uses the Intersection Observer API to make things happen.

#### Setting up

First, we need to prepare some variables and install the observer.

```js
const numSteps = 20.0;

let boxElement;
let prevRatio = 0.0;
let increasingColor = "rgb(40 40 190 / ratio)";
let decreasingColor = "rgb(190 40 40 / ratio)";

// Set things up
window.addEventListener(
  "load",
  (event) => {
    boxElement = document.querySelector("#box");

    createObserver();
  },
  false,
);
```

The constants and variables we set up here are:

`numSteps`

A constant which indicates how many thresholds we want to have between a visibility ratio of 0.0 and 1.0.

`prevRatio`

This variable will be used to record what the visibility ratio was the last time a threshold was crossed; this will let us figure out whether the target element is becoming more or less visible.

`increasingColor`

A string defining a color we'll apply to the target element when the visibility ratio is increasing. The word "ratio" in this string will be replaced with the target's current visibility ratio, so that the element not only changes color but also becomes increasingly opaque as it becomes less obscured.

`decreasingColor`

Similarly, this is a string defining a color we'll apply when the visibility ratio is decreasing.

We call `Window.addEventListener()` to start listening for the `load` event; once the page has finished loading, we get a reference to the element with the ID `"box"` using `querySelector()`, then call the `createObserver()` method we'll create in a moment to handle building and installing the intersection observer.

#### Creating the intersection observer

The `createObserver()` method is called once page load is complete to handle actually creating the new `IntersectionObserver` and starting the process of observing the target element.

```js
function createObserver() {
  let observer;

  let options = {
    root: null,
    rootMargin: "0px",
    threshold: buildThresholdList(),
  };

  observer = new IntersectionObserver(handleIntersect, options);
  observer.observe(boxElement);
}
```

This begins by setting up an `options` object containing the settings for the observer. We want to watch for changes in visibility of the target element relative to the document's viewport, so `root` is `null`. We need no margin, so the margin offset, `rootMargin`, is specified as "0px". This causes the observer to watch for changes in the intersection between the target element's bounds and those of the viewport, without any added (or subtracted) space.

The list of visibility ratio thresholds, `threshold`, is constructed by the function `buildThresholdList()`. The threshold list is built programmatically in this example since there are a number of them and the number is intended to be adjustable.

Once `options` is ready, we create the new observer, calling the `IntersectionObserver()` constructor, specifying a function to be called when intersection crosses one of our thresholds, `handleIntersect()`, and our set of options. We then call `observe()` on the returned observer, passing into it the desired target element.

We could opt to monitor multiple elements for visibility intersection changes with respect to the viewport by calling `observer.observe()` for each of those elements, if we wanted to do so.

#### Building the array of threshold ratios

The `buildThresholdList()` function, which builds the list of thresholds, looks like this:

```js
function buildThresholdList() {
  let thresholds = [];
  let numSteps = 20;

  for (let i = 1.0; i <= numSteps; i++) {
    let ratio = i / numSteps;
    thresholds.push(ratio);
  }

  thresholds.push(0);
  return thresholds;
}
```

This builds the array of thresholds—each of which is a ratio between 0.0 and 1.0, by pushing the value `i/numSteps` onto the `thresholds` array for each integer `i` between 1 and `numSteps`. It also pushes 0 to include that value. The result, given the default value of `numSteps` (20), is the following list of thresholds:

| # | Ratio | # | Ratio |
| --- | --- | --- | --- |
| 0 | 0.05 | 11 | 0.6 |
| 1 | 0.1 | 12 | 0.65 |
| 2 | 0.15 | 13 | 0.7 |
| 3 | 0.2 | 14 | 0.75 |
| 4 | 0.25 | 15 | 0.8 |
| 5 | 0.3 | 16 | 0.85 |
| 6 | 0.35 | 17 | 0.9 |
| 7 | 0.4 | 18 | 0.95 |
| 8 | 0.45 | 19 | 1 |
| 9 | 0.5 | 20 | 0 |
| 10 | 0.55 |

We could, of course, hard-code the array of thresholds into our code, and often that's what you'll end up doing. But this example leaves room for adding configuration controls to adjust the granularity, for example.

#### Handling intersection changes

When the browser detects that the target element (in our case, the one with the ID `"box"`) has been unveiled or obscured such that its visibility ratio crosses one of the thresholds in our list, it calls our handler function, `handleIntersect()`:

```js
function handleIntersect(entries, observer) {
  entries.forEach((entry) => {
    if (entry.intersectionRatio > prevRatio) {
      entry.target.style.backgroundColor = increasingColor.replace(
        "ratio",
        entry.intersectionRatio,
      );
    } else {
      entry.target.style.backgroundColor = decreasingColor.replace(
        "ratio",
        entry.intersectionRatio,
      );
    }

    prevRatio = entry.intersectionRatio;
  });
}
```

For each `IntersectionObserverEntry` in the list `entries`, we look to see if the entry's `intersectionRatio` is going up; if it is, we set the target's `background-color` to the string in `increasingColor` (remember, it's `"rgb(40 40 190 / ratio)"`), replaces the word "ratio" with the entry's `intersectionRatio`. The result: not only does the color get changed, but the transparency of the target element changes, too; as the intersection ratio goes down, the background color's alpha value goes down with it, resulting in an element that's more transparent.

Similarly, if the `intersectionRatio` is going down, we use the string `decreasingColor` and replace the word "ratio" in that with the `intersectionRatio` before setting the target element's `background-color`.

Finally, in order to track whether the intersection ratio is going up or down, we remember the current ratio in the variable `prevRatio`.

### Result

Below is the resulting content. Scroll this page up and down and notice how the appearance of the box changes as you do so.

There's an even more extensive example at Timing element visibility with the Intersection Observer API.

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

| Specification |
| --- |
| Intersection Observer # intersection-observer-interface |

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

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

See also
--------

* Intersection Observer polyfill
* Timing element visibility with the Intersection Observer API
* `IntersectionObserver` and `IntersectionObserverEntry`


ViewTimeline - Web APIs

ViewTimeline
============

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

The **`ViewTimeline`** interface of the Web Animations API represents a view progress timeline (see CSS scroll-driven animations for more details).

Pass a `ViewTimeline` instance to the `Animation()` constructor or the `animate()` method to specify it as the timeline that will control the progress of the animation.

AnimationTimeline

ScrollTimeline

ViewTimelineConstructor
-----------

`ViewTimeline()`
Experimental

Creates a new `ViewTimeline` object instance.

Instance properties
-------------------

*This interface also inherits the properties of its parent, `ScrollTimeline`.*

`subject` Read only
Experimental

Returns a reference to the subject element whose visibility within its nearest ancestor scrollable element (scroller) is driving the progress of the timeline and therefore the animation.

`startOffset` Read only
Experimental

Returns a `CSSNumericValue` representing the starting (0% progress) scroll position of the timeline as an offset from the start of the overflowing section of content in the scroller.

`endOffset` Read only
Experimental

Returns a `CSSNumericValue` representing the ending (100% progress) scroll position of the timeline as an offset from the start of the overflowing section of content in the scroller.

Instance methods
----------------

*This interface inherits the methods of its parent, `ScrollTimeline`.*

Examples
--------

### Displaying the subject and offsets of a view progress timeline

In this example, we animate an element with a `class` of `subject` along a view progress timeline — it animates when moved upwards through the document as it scrolls. We also output the `subject`, `startOffset`, and `endOffset` values to an output element in the top-right corner.

#### HTML

The HTML for the example is shown below.

```html
<div class="content">
  <h1>Content</h1>

  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Risus quis varius quam
    quisque id. Et ligula ullamcorper malesuada proin libero nunc consequat
    interdum varius. Elit ullamcorper dignissim cras tincidunt lobortis feugiat
    vivamus at augue.
  </p>

  <p>
    Dolor sed viverra ipsum nunc aliquet. Sed sed risus pretium quam vulputate
    dignissim. Tortor aliquam nulla facilisi cras. A erat nam at lectus urna
    duis convallis convallis. Nibh ipsum consequat nisl vel pretium lectus.
    Sagittis aliquam malesuada bibendum arcu vitae elementum. Malesuada bibendum
    arcu vitae elementum curabitur vitae nunc sed velit.
  </p>

  <div class="subject animation"></div>

  <p>
    Adipiscing enim eu turpis egestas pretium aenean pharetra magna ac. Arcu
    cursus vitae congue mauris rhoncus aenean vel. Sit amet cursus sit amet
    dictum. Augue neque gravida in fermentum et. Gravida rutrum quisque non
    tellus orci ac auctor augue mauris. Risus quis varius quam quisque id diam
    vel quam elementum. Nibh praesent tristique magna sit amet purus gravida
    quis. Duis ultricies lacus sed turpis tincidunt id aliquet. In egestas erat
    imperdiet sed euismod nisi. Eget egestas purus viverra accumsan in nisl nisi
    scelerisque. Netus et malesuada fames ac.
  </p>

  <div class="output"></div>
</div>
```

#### CSS

The CSS for the example looks like this:

```css
.subject {
  width: 300px;
  height: 200px;
  margin: 0 auto;
  background-color: deeppink;
}

.content {
  width: 75%;
  max-width: 800px;
  margin: 0 auto;
}

.output {
  position: fixed;
  top: 5px;
  right: 5px;
}

p,
h1,
div {
  font-family: Arial, Helvetica, sans-serif;
}

h1 {
  font-size: 3rem;
}

p {
  font-size: 1.5rem;
  line-height: 1.5;
}
```

#### JavaScript

In the JavaScript, we grab references to the `subject` and `output` `<div>`s, then create a new `ViewTimeline`, associating it with the `subject` element to specify that the timeline progress is based on this element's visibility through its scrolling ancestor, setting a `block` axis, and setting `inset` values to adjust the position of the box in which the subject is deemed to be visible.

We then animate the `subject` element with the Web Animations API. Last of all, we display the `subject`, `startOffset`, and `endOffset` values in the `output` element.

```js
const subject = document.querySelector(".subject");
const output = document.querySelector(".output");

const timeline = new ViewTimeline({
  subject,
  axis: "block",
  inset: [CSS.px("200"), CSS.px("300")],
});

subject.animate(
  {
    opacity: [0, 1],
    transform: ["scaleX(0)", "scaleX(1)"],
  },
  {
    fill: "both",
    timeline,
  },
);

output.textContent += `Subject element: ${timeline.subject.nodeName}, `;
output.textContent += `start offset: ${timeline.startOffset}, `;
output.textContent += `end offset: ${timeline.endOffset}.`;
```

#### Result

Scroll to see the subject element being animated.

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

| Specification |
| --- |
| Scroll-driven Animations # viewtimeline-interface |

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

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

See also
--------

* Web Animations API
* CSS scroll-driven animations
* `AnimationTimeline`, `ScrollTimeline`


MediaKeySystemAccess - Web APIs

MediaKeySystemAccess
====================

The **`MediaKeySystemAccess`** interface of the Encrypted Media Extensions API provides access to a Key System for decryption and/or a content protection provider. You can request an instance of this object using the `Navigator.requestMediaKeySystemAccess()` method.

Instance properties
-------------------

`MediaKeySystemAccess.keySystem` Read only

Returns a string identifying the key system being used.

Instance methods
----------------

`MediaKeySystemAccess.createMediaKeys()`

Returns a `Promise` that resolves to a new `MediaKeys` object.

`MediaKeySystemAccess.getConfiguration()`

Returns an object with the supported combination of configuration options.

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

| Specification |
| --- |
| Encrypted Media Extensions # mediakeysystemaccess-interface |

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

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


XPathEvaluator - Web APIs

XPathEvaluator
==============

The `XPathEvaluator` interface allows to compile and evaluate XPath expressions.

Constructor
-----------

`XPathEvaluator()`

Creates a new `XPathEvaluator` object.

Instance methods
----------------

`XPathEvaluator.createExpression()`

Creates a parsed XPath expression with resolved namespaces.

`XPathEvaluator.createNSResolver()`

Adapts any DOM node to resolve namespaces allowing the XPath expression to be evaluated relative to the context of the node where it appeared within the document.

`XPathEvaluator.evaluate()`

Evaluates an XPath expression string and returns a result of the specified type if possible.

Example
-------

### Count the number of `<div>` elements

The following example shows the use of the `XPathEvaluator` interface.

#### HTML

```html
<div>XPath example</div>
<div>Number of <div> elements: <output></output></div>
```

#### JavaScript

```js
const xpath = "//div";
const evaluator = new XPathEvaluator();
const expression = evaluator.createExpression(xpath);
const result = expression.evaluate(
  document,
  XPathResult.ORDERED\_NODE\_SNAPSHOT\_TYPE,
);
document.querySelector("output").textContent = result.snapshotLength;
```

#### Result

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

| Specification |
| --- |
| DOM Standard # interface-xpathevaluator |

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

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

See also
--------

* `document.createExpression()`
* `XPathExpression`


LargestContentfulPaint - Web APIs

LargestContentfulPaint
======================

The `LargestContentfulPaint` interface provides timing information about the largest image or text paint before user input on a web page.

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

The key moment this API provides is the Largest Contentful Paint (LCP) metric. It provides the render time of the largest image or text block visible within the viewport, recorded from when the page first begins to load. The following elements are considered when determining the LCP:

* `<img>` elements.
* `<image>` elements inside an SVG.
* The poster images of `<video>` elements.
* Elements with a `background-image`.
* Groups of text nodes, such as `<p>`.

To measure render times of other elements, use the `PerformanceElementTiming` API.

Additional key paint moments are provided by the `PerformancePaintTiming` API:

* First paint (FP): Time when anything is rendered. Note that the marking of the first paint is optional, not all user agents report it.
* First contentful paint (FCP): Time when the first bit of DOM text or image content is rendered.

`LargestContentfulPaint` inherits from `PerformanceEntry`.

PerformanceEntry

LargestContentfulPaintInstance properties
-------------------

This interface extends the following `PerformanceEntry` properties by qualifying and constraining the properties as follows:

`PerformanceEntry.entryType` Read only
Experimental

Returns "`largest-contentful-paint`".

`PerformanceEntry.name` Read only
Experimental

Always returns an empty string.

`PerformanceEntry.startTime` Read only
Experimental

Returns the value of this entry's `renderTime` if it is not `0`, otherwise the value of this entry's `loadTime`.

`PerformanceEntry.duration` Read only
Experimental

Returns `0`, as `duration` is not applicable to this interface.

It also supports the following properties:

`LargestContentfulPaint.element` Read only

The element that is the current largest contentful paint.

`LargestContentfulPaint.renderTime` Read only

The time the element was rendered to the screen. May not be available if the element is a cross-origin image loaded without the `Timing-Allow-Origin` header.

`LargestContentfulPaint.loadTime` Read only

The time the element was loaded.

`LargestContentfulPaint.size` Read only

The intrinsic size of the element returned as the area (width \* height).

`LargestContentfulPaint.id` Read only

The id of the element. This property returns an empty string when there is no id.

`LargestContentfulPaint.url` Read only

If the element is an image, the request url of the image.

Instance methods
----------------

*This interface also inherits methods from `PerformanceEntry`.*

`LargestContentfulPaint.toJSON()`

Returns a JSON representation of the `LargestContentfulPaint` object.

Examples
--------

### Observing the largest contentful paint

In the following example, an observer is registered to get the largest contentful paint while the page is loading. The `buffered` flag is used to access data from before observer creation.

The LCP API analyzes all content it finds (including content that is removed from the DOM). When new largest content is found, it creates a new entry. It stops searching for larger content when scroll or input events occur, since these events likely introduce new content on the website. Thus the LCP is the last performance entry reported by the observer.

```js
const observer = new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1]; // Use the latest LCP candidate
  console.log("LCP:", lastEntry.startTime);
  console.log(lastEntry);
});
observer.observe({ type: "largest-contentful-paint", buffered: true });
```

### Cross-origin image render time

For security reasons, the value of the `renderTime` property is `0` if the resource is a cross-origin request. Instead the `loadTime` is exposed. To expose cross-origin render time information, the `Timing-Allow-Origin` HTTP response header needs to be set.

For example, to allow `https://developer.mozilla.org` to see `renderTime`, the cross-origin resource should send:

```http
Timing-Allow-Origin: https://developer.mozilla.org
```

Like in the code example, you can use `startTime`, which returns the value of the entry's `renderTime` if it is not `0`, and otherwise the value of this entry's `loadTime`. However, it is recommended to set the `Timing-Allow-Origin` header so that the metrics will be more accurate.

If you use `startTime`, you can flag any inaccuracies by checking if `renderTime` was used:

```js
const isAccurateLCP = entry.renderTime ? true : false;
```

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

| Specification |
| --- |
| Largest Contentful Paint # sec-largest-contentful-paint-interface |

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

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

See also
--------

* Largest Contentful Paint
* First contentful paint
* First paint


SVGFEFloodElement - Web APIs

SVGFEFloodElement
=================

The **`SVGFEFloodElement`** interface corresponds to the `<feFlood>` element.

EventTarget

Node

Element

SVGElement

SVGFEFloodElementInstance properties
-------------------

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

`SVGFEFloodElement.height` Read only

An `SVGAnimatedLength` corresponding to the `height` attribute of the given element.

`SVGFEFloodElement.result` Read only

An `SVGAnimatedString` corresponding to the `result` attribute of the given element.

`SVGFEFloodElement.width` Read only

An `SVGAnimatedLength` corresponding to the `width` attribute of the given element.

`SVGFEFloodElement.x` Read only

An `SVGAnimatedLength` corresponding to the `x` attribute of the given element.

`SVGFEFloodElement.y` Read only

An `SVGAnimatedLength` corresponding to the `y` attribute of the given element.

Instance methods
----------------

*This interface doesn't implement any specific methods, but inherits methods from its parent interface, `SVGElement`.*

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

| Specification |
| --- |
| Filter Effects Module Level 1 # InterfaceSVGFEFloodElement |

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

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

See also
--------

* `<feFlood>`


HTMLModElement - Web APIs

HTMLModElement
==============

The **`HTMLModElement`** interface provides special properties (beyond the regular methods and properties available through the `HTMLElement` interface they also have available to them by inheritance) for manipulating modification elements, that is `<del>` and `<ins>`.

EventTarget

Node

Element

HTMLElement

HTMLModElementInstance properties
-------------------

*Inherits properties from its parent, `HTMLElement`.*

`HTMLModElement.cite`

A string reflecting the `cite` HTML attribute, containing a URI of a resource explaining the change.

`HTMLModElement.dateTime`

A string reflecting the `datetime` HTML attribute, containing a date-and-time string representing a timestamp for the change.

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

| Specification |
| --- |
| HTML Standard # htmlmodelement |

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

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

See also
--------

* HTML elements implementing this interface: `<ins>`, `<del>`.


HTMLTableElement - Web APIs

HTMLTableElement
================

The **`HTMLTableElement`** interface provides special properties and methods (beyond the regular `HTMLElement` object interface it also has available to it by inheritance) for manipulating the layout and presentation of tables in an HTML document.

EventTarget

Node

Element

HTMLElement

HTMLTableElementInstance properties
-------------------

*Inherits properties from its parent, `HTMLElement`.*

`HTMLTableElement.caption`

A `HTMLTableCaptionElement` representing the first `<caption>` that is a child of the element, or `null` if none is found. When set, if the object doesn't represent a `<caption>`, a `DOMException` with the `HierarchyRequestError` name is thrown. If a correct object is given, it is inserted in the tree as the first child of this element and the first `<caption>` that is a child of this element is removed from the tree, if any.

`HTMLTableElement.tHead`

A `HTMLTableSectionElement` representing the first `<thead>` that is a child of the element, or `null` if none is found. When set, if the object doesn't represent a `<thead>`, a `DOMException` with the `HierarchyRequestError` name is thrown. If a correct object is given, it is inserted in the tree immediately before the first element that is neither a `<caption>`, nor a `<colgroup>`, or as the last child if there is no such element, and the first `<thead>` that is a child of this element is removed from the tree, if any.

`HTMLTableElement.tFoot`

A `HTMLTableSectionElement` representing the first `<tfoot>` that is a child of the element, or `null` if none is found. When set, if the object doesn't represent a `<tfoot>`, a `DOMException` with the `HierarchyRequestError` name is thrown. If a correct object is given, it is inserted in the tree immediately before the first element that is neither a `<caption>`, a `<colgroup>`, nor a `<thead>`, or as the last child if there is no such element, and the first `<tfoot>` that is a child of this element is removed from the tree, if any.

`HTMLTableElement.rows` Read only

Returns a live `HTMLCollection` containing all the rows of the element, that is all `<tr>` that are a child of the element, or a child of one of its `<thead>`, `<tbody>` and `<tfoot>` children. The rows members of a `<thead>` appear first, in tree order, and those members of a `<tbody>` last, also in tree order. The `HTMLCollection` is live and is automatically updated when the `HTMLTableElement` changes.

`HTMLTableElement.tBodies` Read only

Returns a live `HTMLCollection` containing all the `<tbody>` of the element. The `HTMLCollection` is live and is automatically updated when the `HTMLTableElement` changes.

### Obsolete Properties

**Warning:** The following properties are obsolete. You should avoid using them.

`HTMLTableElement.align`
Deprecated

A string containing an enumerated value reflecting the `align` attribute. It indicates the alignment of the element's contents with respect to the surrounding context. The possible values are `"left"`, `"right"`, and `"center"`.

`HTMLTableElement.bgColor`
Deprecated

A string containing the background color of the cells. It reflects the obsolete `bgColor` attribute.

`HTMLTableElement.border`
Deprecated

A string containing the width in pixels of the border of the table. It reflects the obsolete `border` attribute.

`HTMLTableElement.cellPadding`
Deprecated

A string containing the width in pixels of the horizontal and vertical space between cell content and cell borders. It reflects the obsolete `cellpadding` attribute.

`HTMLTableElement.cellSpacing`
Deprecated

A string containing the width in pixels of the horizontal and vertical separation between cells. It reflects the obsolete `cellspacing` attribute.

`HTMLTableElement.frame`
Deprecated

A string containing the type of the external borders of the table. It reflects the obsolete `frame` attribute and can take one of the following values: `"void"`, `"above"`, `"below"`, `"hsides"`, `"vsides"`, `"lhs"`, `"rhs"`, `"box"`, or `"border"`.

`HTMLTableElement.rules`
Deprecated

A string containing the type of the internal borders of the table. It reflects the obsolete `rules` attribute and can take one of the following values: `"none"`, `"groups"`, `"rows"`, `"cols"`, or `"all"`.

`HTMLTableElement.summary`
Deprecated

A string containing a description of the purpose or the structure of the table. It reflects the obsolete `summary` attribute.

`HTMLTableElement.width`
Deprecated

A string containing the length in pixels or in percentage of the desired width of the entire table. It reflects the obsolete `width` attribute.

Instance methods
----------------

*Inherits methods from its parent, `HTMLElement`*.

`HTMLTableElement.createTHead()`

Returns an `HTMLTableSectionElement` representing the first `<thead>` that is a child of the element. If none is found, a new one is created and inserted in the tree immediately before the first element that is neither a `<caption>`, nor a `<colgroup>`, or as the last child if there is no such element.

`HTMLTableElement.deleteTHead()`

Removes the first `<thead>` that is a child of the element.

`HTMLTableElement.createTFoot()`

Returns an `HTMLTableSectionElement` representing the first `<tfoot>` that is a child of the element. If none is found, a new one is created and inserted in the tree as the last child.

`HTMLTableElement.deleteTFoot()`

Removes the first `<tfoot>` that is a child of the element.

`HTMLTableElement.createTBody()`

Returns a `HTMLTableSectionElement` representing a new `<tbody>` that is a child of the element. It is inserted in the tree after the last element that is a `<tbody>`, or as the last child if there is no such element.

`HTMLTableElement.createCaption()`

Returns an `HTMLElement` representing the first `<caption>` that is a child of the element. If none is found, a new one is created and inserted in the tree as the first child of the `<table>` element.

`HTMLTableElement.deleteCaption()`

Removes the first `<caption>` that is a child of the element.

`HTMLTableElement.insertRow()`

Returns an `HTMLTableRowElement` representing a new row of the table. It inserts it in the rows collection immediately before the `<tr>` element at the given `index` position. If necessary a `<tbody>` is created. If the `index` is `-1`, the new row is appended to the collection. If the `index` is smaller than `-1` or greater than the number of rows in the collection, a `DOMException` with the value `IndexSizeError` is raised.

`HTMLTableElement.deleteRow()`

Removes the row corresponding to the `index` given in parameter. If the `index` value is `-1` the last row is removed; if it is smaller than `-1` or greater than the amount of rows in the collection, a `DOMException` with the value `IndexSizeError` is raised.

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

| Specification |
| --- |
| HTML Standard # htmltableelement |

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

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

See also
--------

* The HTML element implementing this interface: `<table>`.


GPUBuffer - Web APIs

GPUBuffer
=========

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

The **`GPUBuffer`** interface of the WebGPU API represents a block of memory that can be used to store raw data to use in GPU operations.

A `GPUBuffer` object instance is created using the `GPUDevice.createBuffer()` method.

Instance properties
-------------------

`label`
Experimental

 A string providing a label that can be used to identify the object, for example in
 `GPUError` messages or console warnings.

`mapState`
Experimental
 Read only

An enumerated value representing the mapped state of the `GPUBuffer`.

`size`
Experimental
 Read only

A number representing the length of the `GPUBuffer`'s memory allocation, in bytes.

`usage`
Experimental
 Read only

The bitwise flags representing the allowed usages of the `GPUBuffer`.

Instance methods
----------------

`destroy()`
Experimental

Destroys the `GPUBuffer`.

`getMappedRange()`
Experimental

Returns an `ArrayBuffer` containing the mapped contents of the `GPUBuffer` in the specified range.

`mapAsync()`
Experimental

Maps the specified range of the `GPUBuffer`. Returns a `Promise` that resolves when the `GPUBuffer`'s content is ready to be accessed with `GPUBuffer.getMappedRange()`.

`unmap()`
Experimental

Unmaps the mapped range of the `GPUBuffer`, making its contents available for use by the GPU again.

Examples
--------

In our basic compute demo, we create an output buffer to read GPU calculations to, and a staging buffer to be mapped for JavaScript access.

```js
const output = device.createBuffer({
  size: BUFFER\_SIZE,
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY\_SRC,
});

const stagingBuffer = device.createBuffer({
  size: BUFFER\_SIZE,
  usage: GPUBufferUsage.MAP\_READ | GPUBufferUsage.COPY\_DST,
});
```

Later on, once the `stagingBuffer` contains the results of the GPU computation, a combination of `GPUBuffer` methods are used to read the data back to JavaScript so that it can then be logged to the console:

* `GPUBuffer.mapAsync()` is used to map the `GPUBuffer` for reading.
* `GPUBuffer.getMappedRange()` is used to return an `ArrayBuffer` containing the `GPUBuffer`'s contents.
* `GPUBuffer.unmap()` is used to unmap the `GPUBuffer` again, once we have read the content into JavaScript as needed.

```js
// map staging buffer to read results back to JS
await stagingBuffer.mapAsync(
  GPUMapMode.READ,
  0, // Offset
  BUFFER\_SIZE, // Length
);

const copyArrayBuffer = stagingBuffer.getMappedRange(0, BUFFER\_SIZE);
const data = copyArrayBuffer.slice(0);
stagingBuffer.unmap();
console.log(new Float32Array(data));
```

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

| Specification |
| --- |
| WebGPU # gpubuffer |

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

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

See also
--------

* The WebGPU API


SVGFECompositeElement - Web APIs

SVGFECompositeElement
=====================

The **`SVGFECompositeElement`** interface corresponds to the `<feComposite>` element.

EventTarget

Node

Element

SVGElement

SVGFECompositeElementConstants
---------

| Name | Value | Description |
| --- | --- | --- |
| `SVG_FECOMPOSITE_OPERATOR_UNKNOWN` | 0 |
 The type is not one of predefined types. It is invalid to attempt to
 define a new value of this type or to attempt to switch an existing
 value to this type.
  |
| `SVG_FECOMPOSITE_OPERATOR_OVER` | 1 | Corresponds to the `over` value. |
| `SVG_FECOMPOSITE_OPERATOR_IN` | 2 | Corresponds to the `in` value. |
| `SVG_FECOMPOSITE_OPERATOR_OUT` | 3 | Corresponds to `out` value. |
| `SVG_FECOMPOSITE_OPERATOR_ATOP` | 4 | Corresponds to `atop` value. |
| `SVG_FECOMPOSITE_OPERATOR_XOR` | 5 | Corresponds to `xor` value. |
| `SVG_FECOMPOSITE_OPERATOR_ARITHMETIC` | 6 | Corresponds to `arithmetic` value. |

Instance properties
-------------------

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

`SVGFECompositeElement.height` Read only

An `SVGAnimatedLength` corresponding to the `height` attribute of the given element.

`SVGFECompositeElement.in1` Read only

An `SVGAnimatedString` corresponding to the `in` attribute of the given element.

`SVGFECompositeElement.result` Read only

An `SVGAnimatedString` corresponding to the `result` attribute of the given element.

`SVGFECompositeElement.type` Read only

An `SVGAnimatedEnumeration` corresponding to the `type` attribute of the given element. It takes one of the `SVG_FECOMPOSITE_OPERATOR_*` constants defined on this interface.

`SVGFECompositeElement.values` Read only

An `SVGAnimatedNumberList` corresponding to the `values` attribute of the given element.

`SVGFECompositeElement.width` Read only

An `SVGAnimatedLength` corresponding to the `width` attribute of the given element.

`SVGFECompositeElement.x` Read only

An `SVGAnimatedLength` corresponding to the `x` attribute of the given element.

`SVGFECompositeElement.y` Read only

An `SVGAnimatedLength` corresponding to the `y` attribute of the given element.

Instance methods
----------------

*This interface does not provide any specific methods, but implements those of its parent, `SVGElement`.*

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

| Specification |
| --- |
| Filter Effects Module Level 1 # InterfaceSVGFECompositeElement |

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

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

See also
--------

* `<feComposite>`


PaintWorkletGlobalScope - Web APIs

PaintWorkletGlobalScope
=======================

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

The **`PaintWorkletGlobalScope`** interface of the CSS Painting API represents the global object available inside a paint `Worklet`.

Privacy concerns
----------------

To avoid leaking visited links, this feature is currently disabled in Chrome-based browsers for `<a>` elements with an `href` attribute, and for children of such elements. For details, see the following:

* The CSS Painting API Privacy Considerations section
* The CSS Painting API spec issue "CSS Paint API leaks browsing history"
Instance properties
-------------------

*This interface inherits methods from `WorkletGlobalScope`.*

`PaintWorkletGlobalScope.devicePixelRatio` Read only
Experimental

Returns the current device's ratio of physical pixels to logical pixels.

Instance methods
----------------

*This interface inherits methods from `WorkletGlobalScope`.*

`PaintWorkletGlobalScope.registerPaint()`
Experimental

Registers a class to programmatically generate an image where a CSS property expects a file.

Examples
--------

The following three examples go together to show creating, loading, and using a paint `Worklet`.

### Create a paint worklet

The following shows an example worklet module. This should be in a separate js file. Note that `registerPaint()` is called without a reference to a paint `Worklet`.

```js
class CheckerboardPainter {
  paint(ctx, geom, properties) {
    // The global object here is a PaintWorkletGlobalScope
    // Methods and properties can be accessed directly
    // as global features or prefixed using self
    const dpr = self.devicePixelRatio;

    // Use `ctx` as if it was a normal canvas
    const colors = ["red", "green", "blue"];
    const size = 32;
    for (let y = 0; y < geom.height / size; y++) {
      for (let x = 0; x < geom.width / size; x++) {
        const color = colors[(x + y) % colors.length];
        ctx.beginPath();
        ctx.fillStyle = color;
        ctx.rect(x \* size, y \* size, size, size);
        ctx.fill();
      }
    }
  }
}

// Register our class under a specific name
registerPaint("checkerboard", CheckerboardPainter);
```

### Load a paint worklet

The following example demonstrates loading the above worklet from its js file and does so by feature detection.

```js
if ("paintWorklet" in CSS) {
  CSS.paintWorklet.addModule("checkerboard.js");
}
```

### Use a paint worklet

This example shows how to use a paint `Worklet` in a stylesheet, including the simplest way to provide a fallback if `CSS.paintWorklet` isn't supported.

```html
<style>
 textarea {
 background-image: url(checkerboard);
 background-image: paint(checkerboard);
 }
</style>
<textarea></textarea>
```

You can also use the `@supports` at-rule.

```css
@supports (background: paint(id)) {
  background-image: paint(checkerboard);
}
```

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

| Specification |
| --- |
| CSS Painting API Level 1 # paintworkletglobalscope |

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

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

See also
--------

* CSS Painting API
* Houdini APIs


XRLightEstimate - Web APIs

XRLightEstimate
===============

**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 **`XRLightEstimate`** interface of the WebXR Device API provides the estimated lighting values for an `XRLightProbe` at the time represented by an `XRFrame`.

To get an `XRLightEstimate` object, call the `XRFrame.getLightEstimate()` method.

Instance properties
-------------------

`XRLightEstimate.primaryLightDirection` Read only
Experimental

A `DOMPointReadOnly` representing the direction to the primary light source from the `probeSpace` of an `XRLightProbe`.

`XRLightEstimate.primaryLightIntensity` Read only
Experimental

A `DOMPointReadOnly` (with the `x`, `y`, `z` values mapped to RGB) representing the intensity of the primary light source from the `probeSpace` of an `XRLightProbe`.

`XRLightEstimate.sphericalHarmonicsCoefficients` Read only
Experimental

A `Float32Array` containing 9 spherical harmonics coefficients.

Instance methods
----------------

None.

Examples
--------

### Getting an `XRLightProbe` object

 First, use the `XRSession.requestLightProbe()` method to get a light probe from a session.
 Then, within an `XRFrame` loop, the `getLightEstimate()` method will return a `XRLightEstimate` object containing the lighting values for each frame.

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

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

  // Use light estimate data to light the scene

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

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

| Specification |
| --- |
| WebXR Lighting Estimation API Level 1 # xrlightestimate-interface |

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

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

See also
--------

* `XRFrame.getLightEstimate()`


HTMLLegendElement - Web APIs

HTMLLegendElement
=================

The **`HTMLLegendElement`** is an interface allowing to access properties of the `<legend>` elements. It inherits properties and methods from the `HTMLElement` interface.

EventTarget

Node

Element

HTMLElement

HTMLLegendElementInstance properties
-------------------

*Inherits properties from its parent, `HTMLElement`.*

`HTMLLegendElement.align`
Deprecated

A string representing the alignment relative to the form set.

`HTMLLegendElement.form` Read only

A `HTMLFormElement` representing the form that this legend belongs to. If the legend has a fieldset element as its parent, then this attribute returns the same value as the **form** attribute on the parent fieldset element. Otherwise, it returns `null`.

Instance methods
----------------

*No specific method; inherits methods from its parent, `HTMLElement`.*

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

| Specification |
| --- |
| HTML Standard # htmllegendelement |

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

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

See also
--------

* The HTML element implementing this interface: `<legend>`


Trusted Types API - Web APIs

Trusted Types API
=================

The **Trusted Types API** gives web developers a way to lock down the insecure parts of the `DOM API` to prevent client-side Cross-site scripting (XSS) attacks.

Concepts and Usage
------------------

Client-side, or DOM-based, XSS attacks happen when data controlled by a user (such as that input into a form field) reaches a function that can execute that data. These functions are known as *injection sinks*. DOM-based XSS attacks happen when a user is able to write arbitrary JavaScript code and have it executed by one of these functions.

The Trusted Types API locks down risky injection sinks, requiring you to process the data before passing it to one of these functions. If you use a string, then the browser will throw a `TypeError` and prevent the use of the function.

Trusted Types works alongside Content-Security Policy with the trusted-types and require-trusted-types-for directives.

### Injection Sinks

The Trusted Types API locks down injection sinks that can act as a vector for DOM-XSS attacks. An injection sink is any Web API function that should only be called with trusted, validated or sanitized input. Examples of injection sinks include:

* Functions that insert HTML into the document such as `Element.innerHTML`, `Element.outerHTML`, or `Document.write`.
* Functions that create a new same-origin `Document` with caller-controlled markup such as `DOMParser.parseFromString`.
* Functions that execute code such as `Global_Objects/eval`.
* Setters for `Element` attributes that accept a URL of code to load or execute.

Trusted Types will force you to process the data before passing it to any injection sink rather than use a string. This ensures that the data is trustworthy.

### Trusted Type Policies

A policy is a factory for Trusted Types. Web developers can specify a set of policies used for the creation of typed objects which form the trusted codebase for valid Trusted Type objects.

Interfaces
----------

`TrustedHTML`

Represents a string to insert into an injection sink that will render it as HTML.

`TrustedScript`

Represents a string to insert into an injection sink that could lead to the script being executed.

`TrustedScriptURL`

Represents a string to insert into an injection sink that will parse it as a URL of an external script resource.

`TrustedTypePolicy`

Defines the functions used to create the above Trusted Type objects.

`TrustedTypePolicyFactory`

Creates policies and verifies that Trusted Type object instances were created via one of the policies.

Examples
--------

In the below example we create a policy that will create `TrustedHTML` objects using `TrustedTypePolicyFactory.createPolicy()`. We can then use `TrustedTypePolicy.createHTML` to create a sanitized HTML string to be inserted into the document.

The sanitized value can then be used with `Element.innerHTML` to ensure that no new HTML elements can be injected.

```html
<div id="myDiv"></div>
```

```js
const escapeHTMLPolicy = trustedTypes.createPolicy("myEscapePolicy", {
  createHTML: (string) => string.replace(/>/g, "<"),
});

let el = document.getElementById("myDiv");
const escaped = escapeHTMLPolicy.createHTML("<img src=x onerror=alert(1)>");
console.log(escaped instanceof TrustedHTML); // true
el.innerHTML = escaped;
```

Read more about this example, and discover other ways to sanitize input in the article Prevent DOM-based cross-site scripting vulnerabilities with Trusted Types.

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

| Specification |
| --- |
| Trusted Types  |

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

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

See also
--------

* Prevent DOM-based cross-site scripting vulnerabilities with Trusted Types
* Trusted Types polyfill (also available as an npm package)


ScreenDetails - Web APIs

ScreenDetails
=============

**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.

The **`ScreenDetails`** interface of the Window Management API represents the details of all the screens available to the user's device.

This information is accessed via the `Window.getScreenDetails()` method.

**Note:** `ScreenDetails` is a live object, meaning that it updates as the available screens change. You can therefore keep querying the same object to get updated values, rather than repeatedly calling `getScreenDetails()`.

EventTarget

ScreenDetailsInstance properties
-------------------

*Inherits properties from its parent, `EventTarget`.*

`currentScreen` Read only
Experimental

A single `ScreenDetailed` object representing detailed information about the screen that the current browser window is displayed in.

`screens` Read only
Experimental

An array of `ScreenDetailed` objects, each one representing detailed information about one specific screen available to the user's device.

**Note:** `screens` only includes "extended" displays, not those that mirror another display.

Events
------

`currentscreenchange`
Experimental

Fired when the window's current screen changes in some way — for example available width or height, or orientation.

`screenschange`
Experimental

Fired when screens are connected to or disconnected from the system.

Examples
--------

**Note:** See Multi-window learning environment for a full example (see the source code also).

### Basic screen information access

When `Window.getScreenDetails()` is invoked, the user will be asked for permission to manage windows on all their displays (the status of this permission can be checked using `Permissions.query()` to query `window-management`). If the user grants permission, a `ScreenDetails` object is returned. This object contains details of all the screens available to the user's system.

The below example opens a full-size window on each available display.

```js
const screenDetails = await window.getScreenDetails();

// Open a window on each screen of the device
for (const screen of screenDetails.screens) {
  openWindow(
    screen.availLeft,
    screen.availTop,
    screen.availWidth,
    screen.availHeight,
    url,
  );
}
```

### Responding to changes in available screens

You could use the `screenschange` event to detect when the available screens have changed (perhaps when a screen is plugged in or unplugged), report the change, and update window arrangements to suit the new configuration:

```js
const screenDetails = await window.getScreenDetails();

// Return the number of screens
let noOfScreens = screenDetails.screens.length;

screenDetails.addEventListener("screenschange", () => {
  // If the new number of screens is different to the old number of screens,
  // report the difference
  if (screenDetails.screens.length !== noOfScreens) {
    console.log(
      `The screen count changed from ${noOfScreens} to ${screenDetails.screens.length}`,
    );

    // Update noOfScreens value
    noOfScreens = screenDetails.screens.length;
  }

  // Open, close, or rearrange windows as needed,
  // to fit the new screen configuration
  updateWindows();
});
```

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

| Specification |
| --- |
| Window Management # api-screendetails-interface |

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

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

See also
--------

* Window Management API


InterventionReportBody - Web APIs

InterventionReportBody
======================

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

The `InterventionReportBody` interface of the Reporting API represents the body of an intervention report.

An intervention report is generated when usage of a feature in a web document has been blocked by the browser for reasons such as security, performance, or user annoyance. So for example, a script was been stopped because it was significantly slowing down the browser, or the browser's autoplay policy blocked audio from playing without a user gesture to trigger it.

A deprecation report is generated when a deprecated feature (for example a deprecated API method) is used on a document being observed by a `ReportingObserver`. In addition to the support of this API, receiving useful intervention warnings relies on browser vendors adding these warnings for the relevant features.

ReportBody

InterventionReportBodyConstructor
-----------

An instance of `InterventionReportBody` is returned as the value of `Report.body` when `Report.Type` is `intervention`. The interface has no constructor.

Instance properties
-------------------

This interface also inherits properties from `ReportBody`.

`InterventionReportBody.id`
Experimental
 Read only

A string representing the intervention that generated the report. This can be used to group reports.

`InterventionReportBody.message`
Experimental
 Read only

A string containing a human-readable description of the intervention, including information such how the intervention could be avoided. This typically matches the message a browser will display in its DevTools console when an intervention is imposed, if one is available.

`InterventionReportBody.sourceFile`
Experimental
 Read only

A string containing the path to the source file where the intervention occurred, if known, or `null` otherwise.

`InterventionReportBody.lineNumber`
Experimental
 Read only

A string representing the line in the source file in which the intervention occurred, if known, or `null` otherwise.

`InterventionReportBody.columnNumber`
Experimental
 Read only

A string representing the column in the source file in which the intervention occurred, if known, or `null` otherwise.

Instance methods
----------------

This interface also inherits methods from `ReportBody`.

`InterventionReportBody.toJSON()`
Experimental

A *serializer* which returns a JSON representation of the `InterventionReportBody` object.

Examples
--------

In this example we create a new `ReportingObserver` to observe intervention reports, then print details of each property of the first report to the console.

```js
const options = {
  types: ["intervention"],
  buffered: true,
};

const observer = new ReportingObserver((reports, observer) => {
  const firstReport = reports[0];
  console.log(firstReport.type); // intervention
  console.log(firstReport.body.id);
  console.log(firstReport.body.message);
  console.log(firstReport.body.sourceFile);
  console.log(firstReport.body.lineNumber);
  console.log(firstReport.body.columnNumber);
}, options);
```

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

| Specification |
| --- |
| Intervention Reporting # intervention-report |

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

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

See also
--------

* Reporting API
* The Reporting API


HTMLDataListElement - Web APIs

HTMLDataListElement
===================

The **`HTMLDataListElement`** interface provides special properties (beyond the `HTMLElement` object interface it also has available to it by inheritance) to manipulate `<datalist>` elements and their content.

EventTarget

Node

Element

HTMLElement

HTMLDataListElementInstance properties
-------------------

*Inherits properties from its parent, `HTMLElement`*.

`HTMLDataListElement.options` Read only

A `HTMLCollection` representing a collection of the contained option elements.

Instance methods
----------------

*No specific method; inherits methods from its parent, `HTMLElement`.*

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

| Specification |
| --- |
| HTML Standard # htmldatalistelement |

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

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

See also
--------

* The HTML element implementing this interface: `<datalist>`