WritableStream: locked property - Web APIs

WritableStream: locked property
===============================

The **`locked`** read-only property of the `WritableStream` interface returns a boolean indicating whether the `WritableStream` is locked to a writer.

Value
-----

A boolean value indicating whether or not the writable stream is locked.

Examples
--------

```js
const writableStream = new WritableStream(
  {
    write(chunk) {
      // ...
    },
    close() {
      // ...
    },
    abort(err) {
      // ...
    },
  },
  queuingStrategy,
);

// ...

const writer = writableStream.getWriter();

writableStream.locked;
// should return true, as the stream has been locked to a writer
```

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

| Specification |
| --- |
| Streams Standard # ref-for-ws-locked② |

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

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


RTCDtlsTransport: error event - Web APIs

RTCDtlsTransport: error event
=============================

An `RTCDtlsTransport` receives an `error` event when a transport-level error occurs on the `RTCPeerConnection`.

This event is not cancelable and does not bubble.

Syntax
------

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

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

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

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

An `RTCErrorEvent`. Inherits from `Event`.

Event

RTCErrorEventEvent properties
----------------

*In addition to the standard properties available on the `Event` interface, `RTCErrorEvent` also includes the following:*

`error` Read only

An `RTCError` object specifying the error which occurred; this object includes the type of error that occurred, information about where the error occurred (such as which line number in the SDP or what SCTP cause code was at issue).

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

Transport-level errors will have one of the following values for the specified error's `RTCError` property `errorDetail`:

`dtls-failure`

The negotiation of the DTLS connection failed, or the connection was terminated with a fatal error. The error's `message` contains details about the nature of the error. If a fatal error is *received*, the error object's `receivedAlert` property is set to the value of the DTLSL alert received. If, on the other hand, a fatal error was *sent*, the `sentAlert` is set to the alert's value.

`fingerprint-failure`

The remote certificate for the `RTCDtlsTransport` didn't match any of the fingerprints listed in the SDP. If the remote peer can't match the local certificate against the provided fingerprints, this error doesn't occur, though this situation may result instead in a `dtls-failure` error.

Examples
--------

In this example, the `onerror` event handler property is used to set the handler for the `error` event.

```js
transport.onerror = (ev) => {
  const err = ev.error;

  // …
};
```

**Note:** Since `RTCError` is not one of the legacy errors, the value of `code` is always 0.

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

#### No specification found

No specification data found for `api.RTCDtlsTransport.error_event`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

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

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

See also
--------

* WebRTC API


RTCDtlsTransport: iceTransport property - Web APIs

RTCDtlsTransport: iceTransport property
=======================================

 The read-only **`RTCDtlsTransport`**
 property **`iceTransport`** contains a reference
 to the underlying `RTCIceTransport`.

Value
-----

The underlying `RTCIceTransport` instance.

Examples
--------

TBD

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

| Specification |
| --- |
| WebRTC: Real-Time Communication in Browsers # dom-rtcdtlstransport-icetransport |

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

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

See also
--------

* `RTCDtlsTransport`
* `RTCIceTransport`


RTCDtlsTransport: state property - Web APIs

RTCDtlsTransport: state property
================================

 The **`state`** read-only property of the
 `RTCDtlsTransport` interface provides information which describes a
 Datagram Transport Layer Security (**DTLS**) transport state.

Value
-----

A string. Its value is one of the following:

`new`

The initial state when DTLS has not started negotiating yet.

`connecting`

DTLS is in the process of negotiating a secure connection and verifying the remote fingerprint.

`connected`

DTLS has completed negotiation of a secure connection and verified the remote fingerprint.

`closed`

 The transport has been closed intentionally as the result of receipt of a
 `close_notify` alert, or calling `RTCPeerConnection.close()`.

`failed`

 The transport has failed as the result of an error (such as receipt of an error
 alert or failure to validate the remote fingerprint).

Examples
--------

See `RTCDtlsTransport` for example code.

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

| Specification |
| --- |
| WebRTC: Real-Time Communication in Browsers # dom-rtcdtlstransport-state |

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

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

See also
--------

* WebRTC API
* `RTCDtlsTransport`


Using XMLHttpRequest - Web APIs

Using XMLHttpRequest
====================

In this guide, we'll take a look at how to use `XMLHttpRequest` to issue HTTP requests in order to exchange data between the website and a server.

Examples of both common and more obscure use cases for `XMLHttpRequest` are included.

To send an HTTP request:

1. Create an `XMLHttpRequest` object
2. Open a URL
3. Send the request.

After the transaction completes, the `XMLHttpRequest` object will contain useful information such as the response body and the HTTP status of the result.

```js
function reqListener() {
  console.log(this.responseText);
}

const req = new XMLHttpRequest();
req.addEventListener("load", reqListener);
req.open("GET", "http://www.example.org/example.txt");
req.send();
```

Types of requests
-----------------

A request made via `XMLHttpRequest` can fetch the data in one of two ways, asynchronously or synchronously. The type of request is dictated by the optional `async` argument (the third argument) that is set on the `XMLHttpRequest.open()` method. If this argument is `true` or not specified, the `XMLHttpRequest` is processed asynchronously, otherwise the process is handled synchronously. A detailed discussion and demonstrations of these two types of requests can be found on the synchronous and asynchronous requests page. You can't use synchronous requests outside web workers as it freezes the main interface.

**Note:** The constructor `XMLHttpRequest` isn't limited to only XML documents. It starts with **"XML"** because when it was created the main format that was originally used for asynchronous data exchange was XML.

Handling responses
------------------

There are several types of response attributes defined for the `XMLHttpRequest()` constructor. These tell the client making the `XMLHttpRequest` important information about the status of the response. Some cases where dealing with non-text response types may involve some manipulation and analysis are outlined in the following sections.

### Analyzing and manipulating the responseXML property

If you use `XMLHttpRequest` to get the content of a remote XML document, the `responseXML` property will be a DOM object containing a parsed XML document. This could prove difficult to manipulate and analyze. There are four primary ways of analyzing this XML document:

1. Using XPath to address (or point to) parts of it.
2. Manually Parsing and serializing XML to strings or objects.
3. Using `XMLSerializer` to serialize **DOM trees to strings or to files**.
4. `RegExp` can be used if you always know the content of the XML document beforehand. You might want to remove line breaks, if you use `RegExp` to scan with regard to line breaks. However, this method is a "last resort" since if the XML code changes slightly, the method will likely fail.

**Note:** `XMLHttpRequest` can now interpret HTML for you, using the `responseXML` property. Read the article about HTML in XMLHttpRequest to learn how to do this.

### Processing a `responseText` property containing an HTML document

If you use `XMLHttpRequest` to get the content of a remote HTML webpage, the `responseText` property is a string containing the raw HTML. This could prove difficult to manipulate and analyze. There are three primary ways to analyze and parse this raw HTML string:

1. Use the `XMLHttpRequest.responseXML` property as covered in the article HTML in XMLHttpRequest.
2. Inject the content into the body of a document fragment via `fragment.body.innerHTML` and traverse the DOM of the fragment.
3. `RegExp` can be used if you always know the content of the HTML `responseText` beforehand. You might want to remove line breaks, if you use `RegExp` to scan with regard to line breaks. However, this method is a "last resort" since if the HTML code changes slightly, the method will likely fail.
Handling binary data
--------------------

Although `XMLHttpRequest` is most commonly used to send and receive textual data, it can be used to send and receive binary content. There are several well tested methods for coercing the response of an `XMLHttpRequest` into sending binary data. These involve utilizing the `overrideMimeType()` method on the `XMLHttpRequest` object and is a workable solution.

```js
const req = new XMLHttpRequest();
req.open("GET", url);
// retrieve data unprocessed as a binary string
req.overrideMimeType("text/plain; charset=x-user-defined");
/\* … \*/
```

However, more modern techniques are available, since the `responseType` attribute now supports a number of additional content types, which makes sending and receiving binary data much easier.

For example, consider this snippet, which uses the `responseType` of "`arraybuffer`" to fetch the remote content into a `ArrayBuffer` object, which stores the raw binary data.

```js
const req = new XMLHttpRequest();

req.onload = (e) => {
  const arraybuffer = req.response; // not responseText
  /\* … \*/
};
req.open("GET", url);
req.responseType = "arraybuffer";
req.send();
```

For more examples check out the Sending and Receiving Binary Data page.

Monitoring progress
-------------------

`XMLHttpRequest` provides the ability to listen to various events that can occur while the request is being processed. This includes periodic progress notifications, error notifications, and so forth.

Support for DOM `progress` event monitoring of `XMLHttpRequest` transfers follows the specification for progress events: these events implement the `ProgressEvent` interface. The actual events you can monitor to determine the state of an ongoing transfer are:

`progress`

The amount of data that has been retrieved has changed.

`load`

The transfer is complete; all data is now in the `response`

```js
const req = new XMLHttpRequest();

req.addEventListener("progress", updateProgress);
req.addEventListener("load", transferComplete);
req.addEventListener("error", transferFailed);
req.addEventListener("abort", transferCanceled);

req.open();

// …

// progress on transfers from the server to the client (downloads)
function updateProgress(event) {
  if (event.lengthComputable) {
    const percentComplete = (event.loaded / event.total) \* 100;
    // …
  } else {
    // Unable to compute progress information since the total size is unknown
  }
}

function transferComplete(evt) {
  console.log("The transfer is complete.");
}

function transferFailed(evt) {
  console.log("An error occurred while transferring the file.");
}

function transferCanceled(evt) {
  console.log("The transfer has been canceled by the user.");
}
```

Lines 3-6 add event listeners for the various events that are sent while performing a data transfer using `XMLHttpRequest`.

**Note:** You need to add the event listeners before calling `open()` on the request. Otherwise the `progress` events will not fire.

The progress event handler, specified by the `updateProgress()` function in this example, receives the total number of bytes to transfer as well as the number of bytes transferred so far in the event's `total` and `loaded` fields. However, if the `lengthComputable` field is false, the total length is not known and will be zero.

Progress events exist for both download and upload transfers. The download events are fired on the `XMLHttpRequest` object itself, as shown in the above sample. The upload events are fired on the `XMLHttpRequest.upload` object, as shown below:

```js
const req = new XMLHttpRequest();

req.upload.addEventListener("progress", updateProgress);
req.upload.addEventListener("load", transferComplete);
req.upload.addEventListener("error", transferFailed);
req.upload.addEventListener("abort", transferCanceled);

req.open();
```

**Note:** Progress events are not available for the
 `file:` protocol.

Progress events come in for every chunk of data received, including the last chunk in cases in which the last packet is received and the connection closed before the progress event is fired. In this case, the progress event is automatically fired when the load event occurs for that packet. This lets you now reliably monitor progress by only watching the "progress" event.

 One can also detect all three load-ending conditions (`abort`,
 `load`, or `error`) using the `loadend` event:

```js
req.addEventListener("loadend", loadEnd);

function loadEnd(e) {
  console.log(
    "The transfer finished (although we don't know if it succeeded or not).",
  );
}
```

Note there is no way to be certain, from the information received by the `loadend` event, as to which condition caused the operation to terminate; however, you can use this to handle tasks that need to be performed in all end-of-transfer scenarios.

Get last modified date
----------------------

```js
function getHeaderTime() {
  console.log(this.getResponseHeader("Last-Modified")); // A valid GMTString date or null
}

const req = new XMLHttpRequest();
req.open(
  "HEAD", // use HEAD when you only need the headers
  "yourpage.html",
);
req.onload = getHeaderTime;
req.send();
```

### Do something when last modified date changes

Let's create two functions:

```js
function getHeaderTime() {
  const lastVisit = parseFloat(
    window.localStorage.getItem(`lm\_${this.filepath}`),
  );
  const lastModified = Date.parse(this.getResponseHeader("Last-Modified"));

  if (isNaN(lastVisit) || lastModified > lastVisit) {
    window.localStorage.setItem(`lm\_${this.filepath}`, Date.now());
    isFinite(lastVisit) && this.callback(lastModified, lastVisit);
  }
}

function ifHasChanged(URL, callback) {
  const req = new XMLHttpRequest();
  req.open("HEAD" /\* use HEAD - we only need the headers! \*/, URL);
  req.callback = callback;
  req.filepath = URL;
  req.onload = getHeaderTime;
  req.send();
}
```

And to test:

```js
// Let's test the file "yourpage.html"
ifHasChanged("yourpage.html", function (modified, visit) {
  console.log(
    `The page '${this.filepath}' has been changed on ${new Date(
 nModified,
 ).toLocaleString()}!`,
  );
});
```

If you want to know if the current page has changed, refer to the article about `document.lastModified`.

Cross-site XMLHttpRequest
-------------------------

Modern browsers support cross-site requests by implementing the Cross-Origin Resource Sharing (CORS) standard. As long as the server is configured to allow requests from your web application's origin, `XMLHttpRequest` will work. Otherwise, an `INVALID_ACCESS_ERR` exception is thrown.

Bypassing the cache
-------------------

A cross-browser compatible approach to bypassing the cache is appending a timestamp to the URL, being sure to include a "?" or "&" as appropriate. For example:
```

http://example.com/bar.html -> http://example.com/bar.html?12345
http://example.com/bar.html?foobar=baz -> http://example.com/bar.html?foobar=baz&12345
```

As the local cache is indexed by URL, this causes every request to be unique, thereby bypassing the cache.

You can automatically adjust URLs using the following code:

```js
const req = new XMLHttpRequest();

req.open("GET", url + (/\?/.test(url) ? "&" : "?") + new Date().getTime());
req.send(null);
```

Security
--------

The recommended way to enable cross-site scripting is to use the `Access-Control-Allow-Origin` HTTP header in the response to the XMLHttpRequest.

### XMLHttpRequests being stopped

If you conclude with an XMLHttpRequest receiving `status=0` and `statusText=null`, this means the request was not allowed to be performed. It was `UNSENT`. A likely cause for this is when the `XMLHttpRequest` origin (at the creation of the XMLHttpRequest) has changed when the XMLHttpRequest is subsequently `open()`. This case can happen, for example, when one has an XMLHttpRequest that gets fired on an onunload event for a window, the expected XMLHttpRequest is created when the window to be closed is still there, and finally sending the request (in other words, `open()`) when this window has lost its focus and another window gains focus. The most effective way to avoid this problem is to set a listener on the new window's `DOMActivate` event which is set once the terminated window has its `unload` event triggered.

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

| Specification |
| --- |
| XMLHttpRequest Standard # interface-xmlhttprequest |

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

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

See also
--------

* Using the Fetch API
* HTML in XMLHttpRequest
* HTTP access control
* XMLHttpRequest - REST and the Rich User Experience
* The `XMLHttpRequest` object: WHATWG specification


Sending and Receiving Binary Data - Web APIs

Sending and Receiving Binary Data
=================================

The `responseType` property of the XMLHttpRequest object can be set to change the expected response type from the server. Possible values are the empty string (default), `"arraybuffer"`, `"blob"`, `"document"`, `"json"`, and `"text"`. The `response` property will contain the entity body according to `responseType`, as an `ArrayBuffer`, `Blob`, `Document`, `JSON`, or string. This is `null` if the request is not complete or was not successful.

This example reads an image as a binary file and creates an 8-bit unsigned integer array from the raw bytes. Note that this will not decode the image and read the pixels. You will need a png decoding library for that.

```js
const req = new XMLHttpRequest();
req.open("GET", "/myfile.png", true);
req.responseType = "arraybuffer";

req.onload = (event) => {
  const arrayBuffer = req.response; // Note: not req.responseText
  if (arrayBuffer) {
    const byteArray = new Uint8Array(arrayBuffer);
    byteArray.forEach((element, index) => {
      // do something with each byte in the array
    });
  }
};

req.send(null);
```

You can also read a binary file as a `Blob` by setting the string `"blob"` to the `responseType` property.

```js
const req = new XMLHttpRequest();
req.open("GET", "/myfile.png", true);
req.responseType = "blob";

req.onload = (event) => {
  const blob = req.response;
  // ...
};

req.send();
```

Receiving binary data in older browsers
---------------------------------------

The `loadBinaryResource()` function shown below loads binary data from the specified URL, returning it to the caller.

```js
function loadBinaryResource(url) {
  const req = new XMLHttpRequest();
  req.open("GET", url, false);

  // XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
  req.overrideMimeType("text/plain; charset=x-user-defined");
  req.send(null);
  return req.status === 200 ? req.responseText : "";
}
```

The magic happens in line 5, which overrides the MIME type, forcing the browser to treat it as plain text, using a user-defined character set. This tells the browser not to parse it, and to let the bytes pass through unprocessed.

```js
const filestream = loadBinaryResource(url);
const abyte = filestream.charCodeAt(x) & 0xff; // throw away high-order byte (f7)
```

The example above fetches the byte at offset `x` within the loaded binary data. The valid range for `x` is from 0 to `filestream.length-1`.

See downloading binary streams with XMLHttpRequest for a detailed explanation.

Sending binary data
-------------------

The `send` method of the XMLHttpRequest has been extended to enable easy transmission of binary data by accepting an `ArrayBuffer`, `Blob`, or `File` object.

The following example creates a text file on-the-fly and uses the `POST` method to send the "file" to the server. This example uses plain text, but you can imagine the data being a binary file instead.

```js
const req = new XMLHttpRequest();
req.open("POST", url, true);
req.onload = (event) => {
  // Uploaded
};

const blob = new Blob(["abc123"], { type: "text/plain" });

req.send(blob);
```

Sending typed arrays as binary data
-----------------------------------

You can send JavaScript typed arrays as binary data as well.

```js
// Create a new array with fake data (Consecutive numbers (0 - 255), looping back to 0)
const array = new Uint8Array(512).map((v, i) => i);

const xhr = new XMLHttpRequest();
xhr.open("POST", url, false);
xhr.send(array);
```

This is building a 512-byte array of 8-bit integers and sending it; you can use any binary data you'd like, of course.

Submitting forms and uploading files
------------------------------------

See `FormData`.


HTML in XMLHttpRequest - Web APIs

HTML in XMLHttpRequest
======================

The W3C `XMLHttpRequest` specification adds HTML parsing support to `XMLHttpRequest`, which originally supported only XML parsing. This feature allows Web apps to obtain an HTML resource as a parsed DOM using `XMLHttpRequest`.

To get an overview of how to use `XMLHttpRequest` in general, see Using XMLHttpRequest.

Limitations
-----------

To discourage the synchronous use of `XMLHttpRequest`, HTML support is not available in the synchronous mode. Also, HTML support is only available if the `responseType` property has been set to `"document"`. This limitation avoids wasting time parsing HTML uselessly when legacy code uses `XMLHttpRequest` in the default mode to retrieve `responseText` for `text/html` resources. Also, this limitation avoids problems with legacy code that assumes that `responseXML` is `null` for HTTP error pages (which often have a `text/html` response body).

Usage
-----

Retrieving an HTML resource as a DOM using `XMLHttpRequest` works just like retrieving an XML resource as a DOM using `XMLHttpRequest`, except you can't use the synchronous mode and you have to explicitly request a document by assigning the string `"document"` to the `responseType` property of the `XMLHttpRequest` object after calling `open()` but before calling `send()`.

```js
const xhr = new XMLHttpRequest();
xhr.onload = () => {
  console.log(xhr.responseXML.title);
};
xhr.open("GET", "file.html");
xhr.responseType = "document";
xhr.send();
```

Feature detection
-----------------

### Method 1

This method relies on the "force async" nature of the feature. When you try to set `responseType` of an `XMLHttpRequest` object after it is opened as "sync". This throws an error in the browsers that implement the feature and works on others.

```js
function HTMLinXHR() {
  if (!window.XMLHttpRequest) {
    return false;
  }
  const req = new window.XMLHttpRequest();
  req.open("GET", window.location.href, false);
  try {
    req.responseType = "document";
  } catch (e) {
    return true;
  }
  return false;
}
```

View on JSFiddle

This method is synchronous, does not rely on external assets though it may not be as reliable as method 2 described below since it does not check the actual feature but an indication of that feature.

### Method 2

There are two challenges to detecting exactly if a browser supports HTML parsing in `XMLHttpRequest`. First, the detection result is obtained asynchronously, because HTML support is only available in the asynchronous mode. Second, you have to actually fetch a test document over HTTP, because testing with a `data:` URL would end up testing `data:` URL support at the same time.

Thus, to detect HTML support, a test HTML file is needed on the server. This test file is small and is not well-formed XML:

```html
<title>&&<</title>
```

If the file is named `detect.html`, the following function can be used for detecting HTML parsing support:

```js
function detectHtmlInXhr(callback) {
  if (!window.XMLHttpRequest) {
    setTimeout(function () {
      callback(false);
    }, 0);

    return;
  }
  let done = false;
  const xhr = new window.XMLHttpRequest();
  xhr.onreadystatechange = () => {
    if (xhr.readyState === 4 && !done) {
      done = true;
      callback(
        !!(
          xhr.responseXML &&
          xhr.responseXML.title &&
          xhr.responseXML.title === "&&<"
        ),
      );
    }
  };
  xhr.onabort = xhr.onerror = () => {
    if (!done) {
      done = true;
      callback(false);
    }
  };
  try {
    xhr.open("GET", "detect.html");
    xhr.responseType = "document";
    xhr.send();
  } catch (e) {
    setTimeout(function () {
      if (!done) {
        done = true;
        callback(false);
      }
    }, 0);
  }
}
```

The argument `callback` is a function that will be called asynchronously with `true` as the only argument if HTML parsing is supported and `false` as the only argument if HTML parsing is not supported.

View on JSFiddle

Character encoding
------------------

If the character encoding is declared in the HTTP `Content-Type` header, that character encoding is used. Failing that, if there is a byte order mark, the encoding indicated by the byte order mark is used. Failing that, if there is a `<meta>` element that declares the encoding within the first 1024 bytes of the file, that encoding is used. Otherwise, the file is decoded as UTF-8.

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

| Specification |
| --- |
| XMLHttpRequest Standard # interface-xmlhttprequest |

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

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

See also
--------

* `XMLHttpRequest`
* Using XMLHttpRequest


Synchronous and asynchronous requests - Web APIs

Synchronous and asynchronous requests
=====================================

`XMLHttpRequest` supports both synchronous and asynchronous communications. In general, however, asynchronous requests should be preferred to synchronous requests for performance reasons.

Synchronous requests block the execution of code which causes "freezing" on the screen and an unresponsive user experience.

Asynchronous request
--------------------

If you use an asynchronous `XMLHttpRequest`, you receive a callback when the data has been received. This lets the browser continue to work as normal while your request is being handled.

### Example: send a file to the console log

This is the simplest usage of asynchronous `XMLHttpRequest`.

```js
const xhr = new XMLHttpRequest();
xhr.open("GET", "/bar/foo.txt", true);
xhr.onload = (e) => {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      console.log(xhr.responseText);
    } else {
      console.error(xhr.statusText);
    }
  }
};
xhr.onerror = (e) => {
  console.error(xhr.statusText);
};
xhr.send(null);
```

Line 2 specifies `true` for its third parameter to indicate that the request should be handled asynchronously.

Line 3 creates an event handler function object and assigns it to the request's `onload` attribute. This handler looks at the request's `readyState` to see if the transaction is complete in line 4; if it is, and the HTTP status is 200, the handler dumps the received content. If an error occurred, an error message is displayed.

Line 15 actually initiates the request. The callback routine is called whenever the state of the request changes.

### Example: writing a function to read an external file

In some cases, you must read many external files. This is a standard function which uses the `XMLHttpRequest` object asynchronously in order to switch the content of the read file to a specified listener.

```js
function xhrSuccess() {
  this.callback.apply(this, this.arguments);
}

function xhrError() {
  console.error(this.statusText);
}

function loadFile(url, callback, ...args) {
  const xhr = new XMLHttpRequest();
  xhr.callback = callback;
  xhr.arguments = args;
  xhr.onload = xhrSuccess;
  xhr.onerror = xhrError;
  xhr.open("GET", url, true);
  xhr.send(null);
}
```

Usage:

```js
function showMessage(message) {
  console.log(`${message} ${this.responseText}`);
}

loadFile("message.txt", showMessage, "New message!\n\n");
```

The signature of the utility function ***loadFile*** declares (i) a target URL to read (via an HTTP GET request), (ii) a function to execute on successful completion of the XHR operation, and (iii) an arbitrary list of additional arguments that are passed through the XHR object (via the `arguments` property) to the success callback function.

Line 1 declares a function invoked when the XHR operation completes successfully. It, in turn, invokes the callback function specified in the invocation of the `loadFile` function (in this case, the function `showMessage`) which has been assigned to a property of the XHR object (Line 11). The additional arguments (if any) supplied to the invocation of function loadFile are "applied" to the running of the callback function.

Line 5 declares a function invoked when the XHR operation fails to complete successfully.

Line 11 stores the success callback given as the second argument to `loadFile` in the XHR object's `callback` property.

Line 12 slices the arguments array given to the invocation of `loadFile`. Starting with the third argument, all remaining arguments are collected, assigned to the arguments property of the variable `xhr`, passed to the success callback function `xhrSuccess`., and ultimately supplied to the callback function (in this case, `showMessage`) which is invoked by function `xhrSuccess`.

Line 15 specifies *true* for its third parameter to indicate that the request should be handled asynchronously.

Line 16 actually initiates the request.

### Example: using a timeout

You can use a timeout to prevent your code from hanging while waiting for a read to finish. This is done by setting the value of the `timeout` property on the `XMLHttpRequest` object, as shown in the code below:

```js
function loadFile(url, timeout, callback, ...args) {
  const xhr = new XMLHttpRequest();
  xhr.ontimeout = () => {
    console.error(`The request for ${url} timed out.`);
  };
  xhr.onload = () => {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        callback.apply(xhr, args);
      } else {
        console.error(xhr.statusText);
      }
    }
  };
  xhr.open("GET", url, true);
  xhr.timeout = timeout;
  xhr.send(null);
}
```

Notice the addition of code to handle the "timeout" event by setting the `ontimeout` handler.

Usage:

```js
function showMessage(message) {
  console.log(`${message} ${this.responseText}`);
}

loadFile("message.txt", 2000, showMessage, "New message!\n");
```

Here, we're specifying a timeout of 2000 ms.

Synchronous request
-------------------

**Warning:** Synchronous XHR requests often cause hangs on the web, especially with poor network conditions or when the remote server is slow to respond. Synchronous XHR is now deprecated and should be avoided in favor of asynchronous requests.

All new XHR features such as `timeout` or `abort` are not allowed for synchronous XHR. Doing so will raise an `InvalidAccessError`.

### Example: HTTP synchronous request

This example demonstrates how to make a simple synchronous request.

```js
const request = new XMLHttpRequest();
request.open("GET", "/bar/foo.txt", false); // `false` makes the request synchronous
request.send(null);

if (request.status === 200) {
  console.log(request.responseText);
}
```

Line 3 sends the request. The `null` parameter indicates that no body content is needed for the `GET` request.

Line 5 checks the status code after the transaction is completed. If the result is 200 — HTTP's "OK" result — the document's text content is output to the console.

### Example: Synchronous HTTP request from a Worker

One of the few cases in which a synchronous request does not usually block execution is the use of `XMLHttpRequest` within a `Worker`.

**`example.html`** (the main page):

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>MDN Example</title>
    <script>
 const worker = new Worker("myTask.js");
 worker.onmessage = (event) => {
 alert(`Worker said: ${event.data}`);
 };

 worker.postMessage("Hello");
 </script>
  </head>
  <body>
    …
  </body>
</html>
```

**`myFile.txt`** (the target of the synchronous `XMLHttpRequest` invocation):
```

Hello World!!
```

**`myTask.js`** (the `Worker`):

```js
self.onmessage = (event) => {
  if (event.data === "Hello") {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", "myFile.txt", false); // synchronous request
    xhr.send(null);
    self.postMessage(xhr.responseText);
  }
};
```

**Note:** The effect is asynchronous, because of the use of the `Worker`.

This pattern can be useful, for example in order to interact with the server in the background, or to preload content. See Using web workers for examples and details.

### Adapting Sync XHR use cases to the Beacon API

There are some cases in which the synchronous usage of `XMLHttpRequest` is not replaceable, like during the `unload`, `beforeunload`, and `pagehide` events. You should consider using the `fetch()` API with the `keepalive` flag. When `fetch` with `keepalive` isn't available, you can consider using the `navigator.sendBeacon()` API, which can support these use cases while typically delivering a good UX.

The following example shows theoretical analytics code that attempts to submit data to a server by using a synchronous `XMLHttpRequest` in an unload handler. This results in the unloading of the page to be delayed.

```js
window.addEventListener("unload", logData, false);

function logData() {
  const client = new XMLHttpRequest();
  client.open("POST", "/log", false); // third parameter indicates sync xhr. :(
  client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
  client.send(analyticsData);
}
```

Using the **`sendBeacon()`** method, the data will be transmitted asynchronously to the web server when the User Agent has had an opportunity to do so, **without delaying the unload or affecting the performance of the next navigation.**

The following example shows a theoretical analytics code pattern that submits data to a server by using the **`sendBeacon()`** method.

```js
window.addEventListener("unload", logData, false);

function logData() {
  navigator.sendBeacon("/log", analyticsData);
}
```

See also
--------

* Using XMLHttpRequest
* `navigator.sendBeacon`


Using FormData Objects - Web APIs

Using FormData Objects
======================

The `FormData` object lets you compile a set of key/value pairs to send using the Fetch or XMLHttpRequest API. It is primarily intended for use in sending form data, but can be used independently from forms in order to transmit keyed data. The transmitted data is in the same format that the form's `submit()` method would use to send the data if the form's encoding type were set to `multipart/form-data`.

Creating a `FormData` object from scratch
-----------------------------------------

You can build a `FormData` object yourself, instantiating it then appending fields to it by calling its `append()` method, like this:

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

send.addEventListener("click", async () => {
  const formData = new FormData();
  formData.append("username", "Groucho");
  formData.append("accountnum", 123456);

  // A file <input> element
  const avatar = document.querySelector("#avatar");
  formData.append("avatar", avatar.files[0]);

  // JavaScript file-like object
  const content = '<q id="a"><span id="b">hey!</span></q>';
  const blob = new Blob([content], { type: "text/xml" });
  formData.append("webmasterfile", blob);

  const response = await fetch("http://example.org/post", {
    method: "POST",
    body: formData,
  });
  console.log(await response.json());
});
```

**Note:** The fields `"avatar"` and `"webmasterfile"` both contain a file. The number assigned to the field `"accountnum"` is immediately converted into a string by the `FormData.append()` method (the field's value can be a `Blob`, `File`, or a string. If the value is neither a `Blob` nor a `File`, the value is converted to a string).

This example builds a `FormData` instance containing values for fields named `"username"`, `"accountnum"`, `"avatar"` and `"webmasterfile"`, then uses `fetch()` to send the form's data. The field `"webmasterfile"` is a `Blob`. A `Blob` object represents a file-like object of immutable, raw data. Blobs represent data that isn't necessarily in a JavaScript-native format. The `File` interface is based on `Blob`, inheriting blob functionality and expanding it to support files on the user's system. In order to build a `Blob` you can invoke the `Blob()` constructor.

Retrieving a `FormData` object from an HTML form
------------------------------------------------

To construct a `FormData` object that contains the data from an existing `<form>`, specify that form element when creating the `FormData` object:

**Note:** `FormData` will only use input fields that use the `name` attribute.

```js
const formData = new FormData(someFormElement);
```

For example:

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

send.addEventListener("click", async () => {
  // A <form> element
  const userInfo = document.querySelector("#user-info");
  const formData = new FormData(userInfo);

  const response = await fetch("http://example.org/post", {
    method: "POST",
    body: formData,
  });
  console.log(await response.json());
});
```

You can also append additional data to the `FormData` object between retrieving it from a form and sending it, like this:

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

send.addEventListener("click", async () => {
  const userInfo = document.querySelector("#user-info");
  const formData = new FormData(userInfo);
  formData.append("serialnumber", 12345);

  const response = await fetch("http://example.org/post", {
    method: "POST",
    body: formData,
  });
  console.log(await response.json());
});
```

This lets you augment the form's data before sending it along, to include additional information that's not necessarily user-editable.

Sending files using a `FormData` object
---------------------------------------

You can also send files using `FormData`. Include an `<input>` element of type `file` in your `<form>`:

```html
<form enctype="multipart/form-data" method="post" name="fileinfo" id="fileinfo">
  <p>
    <label
 >Your email address:
      <input
 type="email"
 autocomplete="on"
 name="userid"
 placeholder="email"
 required
 size="32"
 maxlength="64" />
    </label>
  </p>
  <p>
    <label
 >Custom file label:
      <input type="text" name="filelabel" size="12" maxlength="32" />
    </label>
  </p>
  <p>
    <label
 >File to stash:
      <input type="file" name="file" required />
    </label>
  </p>
  <p>
    <input type="submit" value="Stash the file!" />
  </p>
</form>
```

Then you can send it using code like the following:

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

form.addEventListener("submit", async (event) => {
  const formData = new FormData(form);

  formData.append("CustomField", "This is some extra data");

  const response = await fetch("stash.php", {
    method: "POST",
    body: formData,
  });
  event.preventDefault();
});
```

**Note:** If you pass in a reference to the form, the request HTTP method specified in the form will be used over the method specified in the `open()` call.

**Warning:** When using `FormData` to submit POST requests using `XMLHttpRequest` or the Fetch API with the `multipart/form-data` content type (e.g. when uploading files and blobs to the server), *do not* explicitly set the `Content-Type` header on the request. Doing so will prevent the browser from being able to set the `Content-Type` header with the boundary expression it will use to delimit form fields in the request body.

You can also append a `File` or `Blob` directly to the `FormData` object, like this:

```js
data.append("myfile", myBlob, "filename.txt");
```

When using the `append()` method it is possible to use the third optional parameter to pass a filename inside the `Content-Disposition` header that is sent to the server. When no filename is specified (or the parameter isn't supported), the name "blob" is used.

Using a `formdata` event
------------------------

The `formdata` event, more recent than the `FormData` object, is fired on an `HTMLFormElement` object after the entry list representing the form's data is constructed. This happens when the form is submitted, but can also be triggered by the invocation of a `FormData()` constructor.

This allows a `FormData` object to be quickly obtained in response to a `formdata` event firing, rather than needing to put it together yourself.

For example, in the JavaScript we can reference a form:

```js
const formElem = document.querySelector("form");
```

In our `submit` event handler we use `preventDefault` to stop the default form submission, then invoke a `FormData()` constructor to trigger the `formdata` event:

```js
formElem.addEventListener("submit", (e) => {
  // on form submission, prevent default
  e.preventDefault();

  // construct a FormData object, which fires the formdata event
  new FormData(formElem);
});
```

When the `formdata` event fires we can access the `FormData` object using `FormDataEvent.formData`, then do what we like with it (below we post it to the server using `XMLHttpRequest`).

```js
formElem.addEventListener("formdata", (e) => {
  console.log("formdata fired");

  // Get the form data from the event object
  const data = e.formData;
  for (const value of data.values()) {
    console.log(value);
  }

  // Submit the data via fetch()
  fetch("/formHandler", {
    method: "POST",
    body: data,
  });
});
```

Gotchas
-------

The `FormData` object doesn't include data from the fields that are disabled or the fieldsets that are disabled.

See also
--------

* Using the Fetch API
* `HTMLFormElement`
* `Blob`
* Typed Arrays


UserActivation: isActive property - Web APIs

UserActivation: isActive property
=================================

The read-only **`isActive`** property of the `UserActivation` interface indicates whether the current window has transient user activation.

Value
-----

A boolean.

Examples
--------

### Checking if a user gesture was recently performed

Use the `isActive` property to check whether the user is currently interacting with the page.

```js
if (navigator.userActivation.isActive) {
  // proceed to request playing media, for example
}
```

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

| Specification |
| --- |
| HTML Standard # dom-useractivation-isactive |

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

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

See also
--------

* `UserActivation`
* `UserActivation.hasBeenActive`
* Features gated by user activation


UserActivation: hasBeenActive property - Web APIs

UserActivation: hasBeenActive property
======================================

The read-only **`hasBeenActive`** property of the `UserActivation` interface indicates whether the current window has sticky user activation.

Value
-----

A boolean.

Examples
--------

### Checking if a user gesture was ever performed

Use the `hasBeenActive` property to check whether the user has interacted with the page since it was loaded.

```js
if (navigator.userActivation.hasBeenActive) {
  // proceed with auto-playing an animation, for example
}
```

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

| Specification |
| --- |
| HTML Standard # dom-useractivation-hasbeenactive |

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

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

See also
--------

* `UserActivation`
* `UserActivation.isActive`
* Features gated by user activation


Using the Screen Capture API - Web APIs

Using the Screen Capture API
============================

In this article, we will examine how to use the Screen Capture API and its `getDisplayMedia()` method to capture part or all of a screen for streaming, recording, or sharing during a WebRTC conference session.

**Note:** It may be useful to note that recent versions of the WebRTC adapter.js shim include implementations of `getDisplayMedia()` to enable screen sharing on browsers that support it but do not implement the current standard API. This works with at least Chrome, Edge, and Firefox.

Capturing screen contents
-------------------------

Capturing screen contents as a live `MediaStream` is initiated by calling `navigator.mediaDevices.getDisplayMedia()`, which returns a promise that resolves to a stream containing the live screen contents. The `displayMediaOptions` object referenced in the below examples might look something like this:

```js
const displayMediaOptions = {
  video: {
    displaySurface: "browser",
  },
  audio: {
    suppressLocalAudioPlayback: false,
  },
  preferCurrentTab: false,
  selfBrowserSurface: "exclude",
  systemAudio: "include",
  surfaceSwitching: "include",
  monitorTypeSurfaces: "include",
};
```

### Starting screen capture: `async`/`await` style

```js
async function startCapture(displayMediaOptions) {
  let captureStream = null;

  try {
    captureStream =
      await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
  } catch (err) {
    console.error(`Error: ${err}`);
  }
  return captureStream;
}
```

You can write this code either using an asynchronous function and the `await` operator, as shown above, or using the `Promise` directly, as seen below.

### Starting screen capture: `Promise` style

```js
function startCapture(displayMediaOptions) {
  return navigator.mediaDevices
    .getDisplayMedia(displayMediaOptions)
    .catch((err) => {
      console.error(err);
      return null;
    });
}
```

Either way, the user agent responds by presenting a user interface that prompts the user to choose the screen area to share. Both of these implementations of `startCapture()` return the `MediaStream` containing the captured display imagery.

See Options and constraints, below, for more on both how to specify the type of surface you want as well as other ways to adjust the resulting stream.

### Example of a window allowing the user to select a display surface to capture

![Screenshot of Chrome's window for picking a source surface](/en-US/docs/Web/API/Screen_Capture_API/Using_Screen_Capture/chrome-screen-capture-window.png)

You can then use the captured stream, `captureStream`, for anything that accepts a stream as input. The examples below show a few ways to make use of the stream.

### Visible vs. logical display surfaces

For the purposes of the Screen Capture API, a **display surface** is any content object that can be selected by the API for sharing purposes. Sharing surfaces include the contents of a browser tab, a complete window, and a monitor (or group of monitors combined together into one surface).

There are two types of display surface. A **visible display surface** is a surface which is entirely visible on the screen, such as the frontmost window or tab, or the entire screen.

A **logical display surface** is one which is in part or completely obscured, either by being overlapped by another object to some extent, or by being entirely hidden or offscreen. How these are handled by the Screen Capture API varies. Generally, the browser will provide an image which obscures the hidden portion of the logical display surface in some way, such as by blurring or replacing with a color or pattern. This is done for security reasons, as the content that cannot be seen by the user may contain data which they do not want to share.

A user agent might allow the capture of the entire content of an obscured window after gaining permission from the user to do so. In this case, the user agent may include the obscured content, either by getting the current contents of the hidden portion of the window or by presenting the most-recently-visible contents if the current contents are not available.

### Options and constraints

The options object passed into `getDisplayMedia()` is used to set options for the resulting stream.

The `video` and `audio` objects passed into the options object can also hold additional constraints particular to those media tracks. See Properties of shared screen tracks for details about additional constraints for configuring a screen-capture stream that are added to `MediaTrackConstraints`, `MediaTrackSupportedConstraints`, and `MediaTrackSettings`).

None of the constraints are applied in any way until after the content to capture has been selected. The constraints alter what you see in the resulting stream. For example, if you specify a `width` constraint for the video, it's applied by scaling the video after the user selects the area to share. It doesn't establish a restriction on the size of the source itself.

**Note:** Constraints *never* cause changes to the list of sources available for capture by the Screen Sharing API. This ensures that web applications can't force the user to share specific content by restricting the source list until only one item is left.

While display capture is in effect, the machine which is sharing screen contents will display some form of indicator so the user is aware that sharing is taking place.

**Note:** For privacy and security reasons, screen sharing sources are not enumerable using `enumerateDevices()`. Related to this, the `devicechange` event is never sent when there are changes to the sources available for `getDisplayMedia()`.

### Capturing shared audio

`getDisplayMedia()` is most commonly used to capture video of a user's screen (or parts thereof). However, user agents may allow the capture of audio along with the video content. The source of this audio might be the selected window, the entire computer's audio system, or the user's microphone (or a combination of all of the above).

Before starting a project that will require sharing of audio, be sure to check the browser compatibility for `getDisplayMedia()` to see if the browsers you wish compatibility with have support for audio in captured screen streams.

To request that the screen be shared with included audio, the options passed into `getDisplayMedia()` might look like this:

```js
const displayMediaOptions = {
  video: true,
  audio: true,
};
```

This allows the user total freedom to select whatever they want, within the limits of what the user agent supports. This could be refined further by specifying additional options, and constraints inside the `audio` and `video` objects:

```js
const displayMediaOptions = {
  video: {
    displaySurface: "window",
  },
  audio: {
    echoCancellation: true,
    noiseSuppression: true,
    sampleRate: 44100,
    suppressLocalAudioPlayback: true,
  },
  surfaceSwitching: "include",
  selfBrowserSurface: "exclude",
  systemAudio: "exclude",
};
```

In this example the display surface captured is to be the whole window. The audio track should ideally have noise suppression and echo cancellation features enabled, as well as an ideal audio sample rate of 44.1kHz, and suppression of local audio playback.

In addition, the app is hinting to the user agent that it should:

* Provide a control during screen sharing to allow the user to dynamically switch the shared tab.
* Hide the current tab from the list of options presented to the user when capture is requested.
* Not include the system audio among the possible audio sources offered to the user.

Capturing audio is always optional, and even when web content requests a stream with both audio and video, the returned `MediaStream` may still have only one video track, with no audio.

Using the captured stream
-------------------------

The `promise` returned by `getDisplayMedia()` resolves to a `MediaStream` that contains at least one video stream that contains the screen or screen area, and which is adjusted or filtered based upon the constraints specified when `getDisplayMedia()` was called.

### Potential risks

Privacy and security issues surrounding screen sharing are usually not overly serious, but they do exist. The largest potential issue is users inadvertently sharing content they did not wish to share.

For example, privacy and/or security violations can easily occur if the user is sharing their screen and a visible background window happens to contain personal information, or if their password manager is visible in the shared stream. This effect can be amplified when capturing logical display surfaces, which may contain content that the user doesn't know about at all, let alone see.

User agents which take privacy seriously should obfuscate content that is not actually visible onscreen, unless authorization has been given to share that content specifically.

### Authorizing capture of display contents

Before streaming of captured screen contents can begin, the user agent will ask the user to confirm the sharing request, and to select the content to share.

Examples
--------

### Streaming screen capture

In this example, the contents of the captured screen area are streamed into a `<video>` element on the same page.

#### JavaScript

There isn't all that much code needed in order to make this work, and if you're familiar with using `getUserMedia()` to capture video from a camera, you'll find `getDisplayMedia()` to be very familiar.

##### Setup

First, some constants are set up to reference the elements on the page to which we'll need access: the `<video>` into which the captured screen contents will be streamed, a box into which logged output will be drawn, and the start and stop buttons that will turn on and off capture of screen imagery.

The object `displayMediaOptions` contains the options to pass into `getDisplayMedia()`; here, the `displaySurface` property is set to `window`, indicating that the whole window should be captured.

Finally, event listeners are established to detect user clicks on the start and stop buttons.

```js
const videoElem = document.getElementById("video");
const logElem = document.getElementById("log");
const startElem = document.getElementById("start");
const stopElem = document.getElementById("stop");

// Options for getDisplayMedia()

const displayMediaOptions = {
  video: {
    displaySurface: "window",
  },
  audio: false,
};

// Set event listeners for the start and stop buttons
startElem.addEventListener(
  "click",
  (evt) => {
    startCapture();
  },
  false,
);

stopElem.addEventListener(
  "click",
  (evt) => {
    stopCapture();
  },
  false,
);
```

##### Logging content

This example overrides certain `console` methods to output their messages to the `<pre>` block whose ID is `log`.

```js
console.log = (msg) => (logElem.textContent = `${logElem.textContent}\n${msg}`);
console.error = (msg) =>
  (logElem.textContent = `${logElem.textContent}\nError: ${msg}`);
```

This allows us to use `console/log()` and `console.error()` to log information to the log box in the document.

##### Starting display capture

The `startCapture()` method, below, starts the capture of a `MediaStream` whose contents are taken from a user-selected area of the screen. `startCapture()` is called when the "Start Capture" button is clicked.

```js
async function startCapture() {
  logElem.innerHTML = "";

  try {
    videoElem.srcObject =
      await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
    dumpOptionsInfo();
  } catch (err) {
    console.error(err);
  }
}
```

After clearing the contents of the log in order to get rid of any leftover text from the previous attempt to connect, `startCapture()` calls `getDisplayMedia()`, passing into it the constraints object defined by `displayMediaOptions`. Using `await`, the following line of code does not get executed until after the `promise` returned by `getDisplayMedia()` resolves. Upon resolution, the promise returns a `MediaStream`, which will stream the contents of the screen, window, or other region selected by the user.

The stream is connected to the `<video>` element by storing the returned `MediaStream` into the element's `srcObject`.

The `dumpOptionsInfo()` function—which we will look at in a moment—dumps information about the stream to the log box for educational purposes.

If any of that fails, the `catch()` clause outputs an error message to the log box.

##### Stopping display capture

The `stopCapture()` method is called when the "Stop Capture" button is clicked. It stops the stream by getting its track list using `MediaStream.getTracks()`, then calling each track's `stop()` method. Once that's done, `srcObject` is set to `null` to make sure it's understood by anyone interested that there's no stream connected.

```js
function stopCapture(evt) {
  let tracks = videoElem.srcObject.getTracks();

  tracks.forEach((track) => track.stop());
  videoElem.srcObject = null;
}
```

##### Dumping configuration information

For informational purposes, the `startCapture()` method shown above calls a method named `dumpOptions()`, which outputs the current track settings as well as the constraints that were placed upon the stream when it was created.

```js
function dumpOptionsInfo() {
  const videoTrack = videoElem.srcObject.getVideoTracks()[0];

  console.log("Track settings:");
  console.log(JSON.stringify(videoTrack.getSettings(), null, 2));
  console.log("Track constraints:");
  console.log(JSON.stringify(videoTrack.getConstraints(), null, 2));
}
```

The track list is obtained by calling `getVideoTracks()` on the captured screen's `MediaStream`. The settings currently in effect are obtained using `getSettings()` and the established constraints are gotten with `getConstraints()`

#### HTML

The HTML starts with an introductory paragraph, then gets into the meat of things.

```html
<p>
  This example shows you the contents of the selected part of your display.
  Click the Start Capture button to begin.
</p>

<p>
  <button id="start">Start Capture</button> <button id="stop">
    Stop Capture
  </button>
</p>

<video id="video" autoplay></video>
<br />

<strong>Log:</strong>
<br />
<pre id="log"></pre>
```

The key parts of the HTML are:

1. A `<button>` labeled "Start Capture" which, when clicked, calls the `startCapture()` function to request access to, and begin capturing, screen contents.
2. A second button, "Stop Capture", which upon being clicked calls `stopCapture()` to terminate capture of screen contents.
3. A `<video>` into which the captured screen contents are streamed.
4. A `<pre>` block into which logged text is placed by the intercepted `console` method.

#### CSS

The CSS is entirely cosmetic in this example. The video is given a border, and its width is set to occupy nearly the entire available horizontal space (`width: 98%`). `max-width` is set to `860px` to set an absolute upper limit on the video's size,

```css
#video {
  border: 1px solid #999;
  width: 98%;
  max-width: 860px;
}

#log {
  width: 25rem;
  height: 15rem;
  border: 1px solid black;
  padding: 0.5rem;
  overflow: scroll;
}
```

#### Result

The final product looks like this. If your browser supports Screen Capture API, clicking "Start Capture" will present the user agent's interface for selecting a screen, window, or tab to share.

Security
--------

In order to function when Permissions Policy is enabled, you will need the `display-capture` permission. This can be done using the `Permissions-Policy` HTTP header or—if you're using the Screen Capture API in an `<iframe>`, the `<iframe>` element's `allow` attribute.

For example, this line in the HTTP headers will enable Screen Capture API for the document and any embedded `<iframe>` elements that are loaded from the same origin:

```http
Permissions-Policy: display-capture=(self)
```

If you're performing screen capture within an `<iframe>`, you can request permission just for that frame, which is clearly more secure than requesting permission more generally:

```html
<iframe src="https://mycode.example.net/etc" allow="display-capture"> </iframe>
```

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

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

See also
--------

* Screen Capture API
* Media Capture and Streams API
* Taking still photos with WebRTC
* `HTMLCanvasElement.captureStream()` to obtain a `MediaStream` with the live contents of a `<canvas>`


PushEvent: data property - Web APIs

PushEvent: data property
========================

The `data` read-only property of the **`PushEvent`** interface returns a reference to a `PushMessageData` object containing data sent to the `PushSubscription`.

Value
-----

A `PushMessageData` object or `null` if no `data` member is passed when the event instance initialized.

Examples
--------

The following example takes data from a PushEvent and displays it on all of the service workers' clients.

```js
self.addEventListener("push", (event) => {
  if (!(self.Notification && self.Notification.permission === "granted")) {
    return;
  }

  const data = event.data?.json() ?? {};
  const title = data.title || "Something Has Happened";
  const message =
    data.message || "Here's something you might want to check out.";
  const icon = "images/new-notification.png";

  const notification = new Notification(title, {
    body: message,
    tag: "simple-push-demo-notification",
    icon,
  });

  notification.addEventListener("click", () => {
    clients.openWindow(
      "https://example.blog.com/2015/03/04/something-new.html",
    );
  });
});
```

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

| Specification |
| --- |
| Push API # dom-pushevent-data |

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

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


PushEvent: PushEvent() constructor - Web APIs

PushEvent: PushEvent() constructor
==================================

 The **`PushEvent()`** constructor creates a new
 `PushEvent` object. Note that this constructor is exposed only to a
 service worker context.

Syntax
------

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

### Parameters

`type`

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

`options` Optional

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

`data`

 The data you want the `PushEvent` to contain, if any.
 When the constructor is invoked, the `PushEvent.data` property of the resulting object will be set
 to a new `PushMessageData` object containing these bytes.

### Return value

A new `PushEvent` object.

Examples
--------

```js
const dataInit = {
  data: "Some sample text",
};

const myPushEvent = new PushEvent("push", dataInit);

myPushEvent.data.text(); // should return 'Some sample text'
```

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

| Specification |
| --- |
| Push API # dom-pushevent-constructor |

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

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

See also
--------

* Push API
* Service Worker API


CSSRuleList: length property - Web APIs

CSSRuleList: length property
============================

The **`length`** property of the `CSSRuleList` interface returns the number of `CSSRule` objects in the list.

Value
-----

An integer.

Examples
--------

In the following example the number of items in the `CSSRuleList` named `myRules` is printed to the console.

```js
let myRules = document.styleSheets[0].cssRules;
console.log(myRules.length);
```

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

| Specification |
| --- |
| CSS Object Model (CSSOM) # dom-cssrulelist-length |

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

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


CSSRuleList: item() method - Web APIs

CSSRuleList: item() method
==========================

The **`item()`** method of the `CSSRuleList` interface returns the `CSSRule` object at the specified `index` or `null` if the specified `index` doesn't exist.

Syntax
------

```js
item(index)
```

### Parameters

`index`

An integer.

### Return value

A `CSSRule`.

Examples
--------

In the following example, we assume that the `myRules` list has three items only.

```js
let myRules = document.styleSheets[0].cssRules;
console.log(myRules.item(0)); // Logs the first CSSRule item from this list

// Accessing non-existing items using this method will return null instead of undefined
console.log(myRules.item(5)); // null
console.log(myRules[5]); // undefined
```

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

| Specification |
| --- |
| CSS Object Model (CSSOM) # dom-cssrulelist-item |

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

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


MIDIInput: midimessage event - Web APIs

MIDIInput: midimessage event
============================

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

The `midimessage` event of the Web MIDI API is fired when the MIDI port corresponding to this `MIDIInput` finishes receiving one or more MIDI messages. An instance of `MIDIMessageEvent` containing the message that was received is passed to the event handler.

Syntax
------

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

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

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

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

An `MIDIMessageEvent`. Inherits from `Event`.

Event

MIDIMessageEventEvent properties
----------------

*This interface also inherits properties from `Event`.*

`MIDIMessageEvent.data`

A `Uint8Array` containing the data bytes of a single MIDI message. See the MIDI specification for more information on its form.

Examples
--------

In the following example `midimessage` events are listened for on all input ports. When a message is received the `MIDIMessageEvent.data` property is printed to the console.

```js
inputs.forEach((input) => {
  input.onmidimessage = (message) => {
    console.log(message.data);
  };
});
```

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

| Specification |
| --- |
| Web MIDI API # dom-midiinput-onmidimessage |

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

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


AudioNode: numberOfInputs property - Web APIs

AudioNode: numberOfInputs property
==================================

 The `numberOfInputs` property of
 the `AudioNode` interface returns the number of inputs feeding the
 node. Source nodes are defined as nodes having a `numberOfInputs`
 property with a value of 0.

Value
-----

An integer ≥ 0.

Examples
--------

```js
const audioCtx = new AudioContext();

const oscillator = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();

oscillator.connect(gainNode).connect(audioCtx.destination);

console.log(oscillator.numberOfInputs); // 0
console.log(gainNode.numberOfInputs); // 1
console.log(audioCtx.destination.numberOfInputs); // 1
```

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

| Specification |
| --- |
| Web Audio API # dom-audionode-numberofinputs |

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

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

See also
--------

* Using the Web Audio API


AudioNode: context property - Web APIs

AudioNode: context property
===========================

 The read-only `context` property of the
 `AudioNode` interface returns the associated
 `BaseAudioContext`, that is the object representing the processing graph
 the node is participating in.

Value
-----

 The `AudioContext` or `OfflineAudioContext` object that was
 used to construct this `AudioNode`.

Examples
--------

```js
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioCtx = new AudioContext();

const oscillator = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();
oscillator.connect(gainNode).connect(audioCtx.destination);

console.log(oscillator.context); // AudioContext
console.log(oscillator.context === audioCtx); // true
```

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

| Specification |
| --- |
| Web Audio API # dom-audionode-context |

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

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

See also
--------

* Using the Web Audio API


AudioNode: disconnect() method - Web APIs

AudioNode: disconnect() method
==============================

The **`disconnect()`** method of the `AudioNode` interface lets you disconnect one or more nodes from the node on which the method is called.

Syntax
------

```js
disconnect()
```

### Parameters

There are several versions of the `disconnect()` method, which accept different combinations of parameters to control which nodes to disconnect from. If no parameters are provided, all outgoing connections are disconnected.

`destination` Optional

An `AudioNode` or `AudioParam` specifying the node or nodes to disconnect from. If this value is an `AudioNode`, a single node is disconnected from, with any other, optional, parameters (`output` and/or `input`) further limiting which inputs and/or outputs should be disconnected. If this value is an `AudioParam`, then the connection to that `AudioParam` is terminated, and the node's contributions to that computed parameter become 0 going forward once the change takes effect.

`output` Optional

An index describing which output from the current `AudioNode` is to be disconnected. The index numbers are defined according to the number of output channels (see Audio channels).

`input` Optional

An index describing which input into the specified destination `AudioNode` is to be disconnected. The index numbers are defined according to the number of input channels (see Audio channels).

### Return value

None (`undefined`).

### Exceptions

`IndexSizeError` `DOMException`

Thrown if the value specified as `input` or `output` is invalid, referring to a node which doesn't exist or is outside the permitted range.

`InvalidAccessError` `DOMException`

Thrown if the node on which `disconnect()` is called isn't connected to the specified `destination` node.

Examples
--------

```js
const AudioContext = window.AudioContext || window.webkitAudioContext;

const audioCtx = new AudioContext();

const oscillator = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();

oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);

gainNode.disconnect();
```

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

| Specification |
| --- |
| Web Audio API # dom-audionode-disconnect |

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

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

See also
--------

* Using the Web Audio API


AudioNode: channelCount property - Web APIs

AudioNode: channelCount property
================================

The **`channelCount`** property of the `AudioNode` interface represents an integer used to determine how many channels are used when up-mixing and down-mixing connections to any inputs to the node.

`channelCount`'s usage and precise definition depend on the value of `AudioNode.channelCountMode`:

* It is ignored if the `channelCountMode` value is `max`.
* It is used as a maximum value if the `channelCountMode` value is `clamped-max`.
* It is used as the exact value if the `channelCountMode` value is `explicit`.
Value
-----

An integer.

Examples
--------

```js
const audioCtx = new AudioContext();

const oscillator = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();

oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);

oscillator.channelCount;
```

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

| Specification |
| --- |
| Web Audio API # dom-audionode-channelcount |

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

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

See also
--------

* Using the Web Audio API


AudioNode: numberOfOutputs property - Web APIs

AudioNode: numberOfOutputs property
===================================

 The `numberOfOutputs` property of
 the `AudioNode` interface returns the number of outputs coming out of
 the node. Destination nodes — like `AudioDestinationNode` — have
 a value of 0 for this attribute.

Value
-----

An integer ≥ 0.

Examples
--------

```js
const audioCtx = new AudioContext();

const oscillator = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();

oscillator.connect(gainNode).connect(audioCtx.destination);

console.log(oscillator.numberOfOutputs); // 1
console.log(gainNode.numberOfOutputs); // 1
console.log(audioCtx.destination.numberOfOutputs); // 0
```

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

| Specification |
| --- |
| Web Audio API # dom-audionode-numberofoutputs |

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

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

See also
--------

* Using the Web Audio API


AudioNode: channelInterpretation property - Web APIs

AudioNode: channelInterpretation property
=========================================

The **`channelInterpretation`** property of the `AudioNode` interface represents an enumerated value describing how input channels are mapped to output channels when the number of inputs/outputs is different. For example, this setting defines how a mono input will be up-mixed to a stereo or 5.1 channel output, or how a quad channel input will be down-mixed to a stereo or mono output.

The property has two options: `speakers` and `discrete`. These are documented in Basic concepts behind Web Audio API > up-mixing and down-mixing.

Value
-----

The values are documented in Basic concepts behind Web Audio API > up-mixing and down-mixing.

In summary:

`speakers`

Use set of "standard" mappings for combinations of common speaker input and outputs setups (mono, stereo, quad, 5.1). For example, with this setting a mono channel input will output to both channels of a stereo output.

`discrete`

Input channels are mapped to output channels in order. If there are more inputs that outputs the additional inputs are dropped; if there are fewer than the unused outputs are silent.

Examples
--------

```js
const audioCtx = new AudioContext();

const oscillator = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();

oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);

oscillator.channelInterpretation = "discrete";
```

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

| Specification |
| --- |
| Web Audio API # dom-audionode-channelinterpretation |

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

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

See also
--------

* Using the Web Audio API


AudioNode: connect() method - Web APIs

AudioNode: connect() method
===========================

 The `connect()` method of the `AudioNode` interface lets
 you connect one of the node's outputs to a target, which may be either another
 `AudioNode` (thereby directing the sound data to the specified node) or an
 `AudioParam`, so that the node's output data is automatically used to
 change the value of that parameter over time.

Syntax
------

```js
connect(destination)
connect(destination, outputIndex)
connect(destination, outputIndex, inputIndex)
```

### Parameters

`destination`

The `AudioNode` or `AudioParam` to which to connect.

`outputIndex` Optional

 An index specifying which output of the current `AudioNode` to connect to
 the destination. The index numbers are defined according to the number of output
 channels (see Audio channels).
 While you can only connect a given output to a given input once
 (repeated attempts are ignored), you can connect an output to multiple inputs by
 calling `connect()` repeatedly. This makes fan-out
 possible. The default value is 0.

`inputIndex` Optional

 An index describing which input of the destination you want to connect the current
 `AudioNode` to; the default is 0. The index numbers are defined according
 to the number of input channels
 (see Audio channels). It is possible to connect an `AudioNode` to another
 `AudioNode`, which in turn connects back to the first
 `AudioNode`, creating a cycle.

### Return value

 If the destination is a node, `connect()` returns a reference to the
 destination `AudioNode` object, allowing you to chain multiple
 `connect()` calls. In some browsers, older implementations of this interface
 return `undefined`.

 If the destination is an `AudioParam`, `connect()` returns
 `undefined`.

### Exceptions

`IndexSizeError` `DOMException`

Thrown if the value specified as `outputIndex` or `inputIndex` doesn't correspond to an existing input or output.

`InvalidAccessError` `DOMException`

Thrown if the destination node is not part of the same audio context as the source node.

`NotSupportedError` `DOMException`

 Thrown if the specified connection would create a cycle (in which the audio loops back through
 the same nodes repeatedly) and there are no `DelayNode` objects in the cycle to
 prevent the resulting waveform from getting stuck constructing the same audio frame
 indefinitely. Also thrown if the `inputIndex` parameter is used while the destination is an `AudioParam`.

Examples
--------

### Connecting to an audio input

 The most obvious use of the `connect()` method is to direct the audio output
 from one node into the audio input of another node for further processing. For example,
 you might send the audio from a `MediaElementAudioSourceNode`—that is, the
 audio from an HTML media element such as `<audio>`—through a band pass
 filter implemented using a `BiquadFilterNode` to reduce noise before then
 sending the audio along to the speakers.

 This example creates an oscillator, then links it to a gain node, so that the gain node
 controls the volume of the oscillator node.

```js
const audioCtx = new AudioContext();

const oscillator = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();

oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);
```

### AudioParam example

 In this example, we will be altering the gain value of a `GainNode` using
 an `OscillatorNode` with a slow frequency value. This technique is know as
 an *LFO*-controlled parameter.

```js
const audioCtx = new AudioContext();

// create an normal oscillator to make sound
const oscillator = audioCtx.createOscillator();

// create a second oscillator that will be used as an LFO (Low-frequency
// oscillator), and will control a parameter
const lfo = audioCtx.createOscillator();

// set the frequency of the second oscillator to a low number
lfo.frequency.value = 2.0; // 2Hz: two oscillations per second

// create a gain whose gain AudioParam will be controlled by the LFO
const gain = audioCtx.createGain();

// connect the LFO to the gain AudioParam. This means the value of the LFO
// will not produce any audio, but will change the value of the gain instead
lfo.connect(gain.gain);

// connect the oscillator that will produce audio to the gain
oscillator.connect(gain);

// connect the gain to the destination so we hear sound
gain.connect(audioCtx.destination);

// start the oscillator that will produce audio
oscillator.start();

// start the oscillator that will modify the gain value
lfo.start();
```

#### AudioParam notes

It is possible to connect an `AudioNode` output to more than one `AudioParam`, and more than one AudioNode output to a single `AudioParam`, with multiple calls to `connect()`. Fan-in and fan-out are therefore supported.

 An `AudioParam` will take the rendered audio data from any
 `AudioNode` output connected to it and convert it to mono by down-mixing
 (if it is not already mono). Next, it will mix it together with any other such outputs,
 and the intrinsic parameter value (the value the `AudioParam` would
 normally have without any audio connections), including any timeline changes scheduled
 for the parameter.

 Therefore, it is possible to choose the range in which an `AudioParam`
 will change by setting the value of the `AudioParam` to the central
 frequency, and to use a `GainNode` between the audio source and the
 `AudioParam` to adjust the range of the `AudioParam` changes.

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

| Specification |
| --- |
| Web Audio API # dom-audionode-connect |
| Web Audio API # dom-audionode-connect-destinationparam-output |

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

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

See also
--------

* Using the Web Audio API


AudioNode: channelCountMode property - Web APIs

AudioNode: channelCountMode property
====================================

The `channelCountMode` property of the `AudioNode` interface represents an enumerated value describing the way channels must be matched between the node's inputs and outputs.

Value
-----

The possible values of the `channelCountMode` enumerated value, and their meanings are:

`max`

 The number of channels is equal to the maximum number of channels of all connections.
 In this case, `channelCount` is ignored and only up-mixing happens.

The following AudioNode children default to this value: `GainNode`, `DelayNode`, `ScriptProcessorNode`, `BiquadFilterNode`, `WaveShaperNode`.

`clamped-max`

The number of channels is equal to the maximum number of channels of all connections, clamped to the value of `channelCount`.

The following AudioNode children default to this value: `PannerNode`, `ConvolverNode`, `DynamicsCompressorNode`

`explicit`

The number of channels is defined by the value of `channelCount`.

The following AudioNode children default to this value: `AudioDestinationNode`, `AnalyserNode`, `ChannelSplitterNode`, `ChannelMergerNode`

**Note:** In older versions of the spec, the default for a `ChannelSplitterNode` was `max`.

Examples
--------

```js
const audioCtx = new AudioContext();

const oscillator = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();

oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);

oscillator.channelCountMode = "explicit";
```

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

| Specification |
| --- |
| Web Audio API # dom-audionode-channelcountmode |

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

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

See also
--------

* Using the Web Audio API


WebGLRenderingContext: stencilMask() method - Web APIs

WebGLRenderingContext: stencilMask() method
===========================================

 The **`WebGLRenderingContext.stencilMask()`** method of the WebGL API controls enabling and disabling of
 both the front and back writing of individual bits in the stencil planes.

 The `WebGLRenderingContext.stencilMaskSeparate()` method can set front and
 back stencil writemasks to different values.

Syntax
------

```js
stencilMask(mask)
```

### Parameters

`mask`

 A `GLuint` specifying a bit mask to enable or disable writing of
 individual bits in the stencil planes. By default, the mask is all 1.

### Return value

None (`undefined`).

Examples
--------

```js
gl.stencilMask(110101);
```

 To get the current stencil masks, query the `STENCIL_WRITEMASK`,
 `STENCIL_BACK_WRITEMASK`, or `STENCIL_BITS` constants.

```js
gl.getParameter(gl.STENCIL\_WRITEMASK);
// 110101
gl.getParameter(gl.STENCIL\_BACK\_WRITEMASK);
// 110101
gl.getParameter(gl.STENCIL\_BITS);
// 0
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.3 |

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

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

See also
--------

* `WebGLRenderingContext.colorMask()`
* `WebGLRenderingContext.depthMask()`
* `WebGLRenderingContext.stencilMaskSeparate()`


WebGLRenderingContext: blendFunc() method - Web APIs

WebGLRenderingContext: blendFunc() method
=========================================

 The **`WebGLRenderingContext.blendFunc()`** method of the WebGL API defines which function is used for
 blending pixel arithmetic.

Syntax
------

```js
blendFunc(sfactor, dfactor)
```

### Parameters

`sfactor`

 A `WebGL_API.Types` specifying a multiplier for the source blending factors. The
 default value is `gl.ONE`. For possible values, see below.

`dfactor`

 A `WebGL_API.Types` specifying a multiplier for the destination blending
 factors. The default value is `gl.ZERO`. For possible values, see below.

### Return value

None (`undefined`).

### Exceptions

* If *sfactor* or *dfactor* is not one of the listed possible values, a
 `gl.INVALID_ENUM` error is thrown.
* If a constant color and a constant alpha value are used together as source and
 destination factors, a `gl.INVALID_ENUM` error is thrown.
Constants
---------

The following constants can be used for *sfactor* and *dfactor*.

 The formula for the blending color can be described like this: color(RGBA) =
 (sourceColor \* *sfactor*) + (destinationColor \* *dfactor*). The RGBA
 values are between 0 and 1.

 In the following table, RS, GS, BS, AS represent respectively
 the *red*, *green*, *blue* and *alpha* component of the source, while
 RD, GD, BD, AD represent respectively
 the *red*, *green*, *blue* and *alpha* component of the destination.
 Similarly, RC, GC, BC, AC represent respectively
 the *red*, *green*, *blue* and *alpha* component of a constant color. They are all values between 0 and 1, included.

| Constant | Factor | Description |
| --- | --- | --- |
| `gl.ZERO` | 0,0,0,0 | Multiplies all colors by 0. |
| `gl.ONE` | 1,1,1,1 | Multiplies all colors by 1. |
| `gl.SRC_COLOR` | RS, GS, BS, AS | Multiplies all colors by the source colors. |
| `gl.ONE_MINUS_SRC_COLOR` | 1-RS, 1-GS, 1-BS, 1-AS | Multiplies all colors by 1 minus each source color. |
| `gl.DST_COLOR` | RD, GD, BD, AD | Multiplies all colors by the destination color. |
| `gl.ONE_MINUS_DST_COLOR` | 1-RD, 1-GD, 1-BD, 1-AD | Multiplies all colors by 1 minus each destination color. |
| `gl.SRC_ALPHA` | AS, AS, AS, AS | Multiplies all colors by the source alpha value. |
| `gl.ONE_MINUS_SRC_ALPHA` | 1-AS, 1-AS, 1-AS, 1-AS | Multiplies all colors by 1 minus the source alpha value. |
| `gl.DST_ALPHA` | AD, AD, AD, AD | Multiplies all colors by the destination alpha value. |
| `gl.ONE_MINUS_DST_ALPHA` | 1-AD, 1-AD, 1-AD, 1-AD | Multiplies all colors by 1 minus the destination alpha value. |
| `gl.CONSTANT_COLOR` | RC, GC, BC, AC | Multiplies all colors by a constant color. |
| `gl.ONE_MINUS_CONSTANT_COLOR` | 1-RC, 1-GC, 1-BC, 1-AC | Multiplies all colors by 1 minus a constant color. |
| `gl.CONSTANT_ALPHA` | AC, AC, AC, AC | Multiplies all colors by a constant alpha value. |
| `gl.ONE_MINUS_CONSTANT_ALPHA` | 1-AC, 1-AC, 1-AC, 1-AC | Multiplies all colors by 1 minus a constant alpha value. |
| `gl.SRC_ALPHA_SATURATE` |
 min(AS, 1 - AD), min(AS, 1 -
 AD), min(AS, 1 - AD), 1
  |
 Multiplies the RGB colors by the smaller of either the source alpha
 value or the value of 1 minus the destination alpha value. The alpha
 value is multiplied by 1.
  |

Examples
--------

 To use the blend function, you first have to activate blending with
 `WebGLRenderingContext.enable()` with the argument `gl.BLEND`.

```js
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC\_COLOR, gl.DST\_COLOR);
```

 To get the current blend function, query the `BLEND_SRC_RGB`,
 `BLEND_SRC_ALPHA`, `BLEND_DST_RGB`, and
 `BLEND_DST_ALPHA` constants which return one of the blend function constants.

```js
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC\_COLOR, gl.DST\_COLOR);
gl.getParameter(gl.BLEND\_SRC\_RGB) === gl.SRC\_COLOR;
// true
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.3 |

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

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

See also
--------

* `WebGLRenderingContext.blendColor()`
* `WebGLRenderingContext.blendEquation()`


WebGLRenderingContext: clearDepth() method - Web APIs

WebGLRenderingContext: clearDepth() method
==========================================

 The **`WebGLRenderingContext.clearDepth()`** method of the WebGL API specifies the clear value for the
 depth buffer.

 This specifies what depth value to use when calling the
 `clear()` method. The value is clamped
 between 0 and 1.

Syntax
------

```js
clearDepth(depth)
```

### Parameters

`depth`

 A `GLclampf` specifying the depth value used when the depth buffer is
 cleared. Default value: 1.

### Return value

None (`undefined`).

Examples
--------

```js
gl.clearDepth(0.5);
```

 To get the current depth clear value, query the `DEPTH_CLEAR_VALUE`
 constant.

```js
gl.getParameter(gl.DEPTH\_CLEAR\_VALUE);
// 0.5
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.3 |

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

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

See also
--------

* `WebGLRenderingContext.clear()`
* `WebGLRenderingContext.clearColor()`
* `WebGLRenderingContext.clearStencil()`


WebGLRenderingContext: texParameter[fi]() method - Web APIs

WebGLRenderingContext: texParameter[fi]() method
================================================

 The **`WebGLRenderingContext.texParameter[fi]()`** methods of
 the WebGL API set texture parameters.

Syntax
------

```js
texParameterf(target, pname, param)
texParameteri(target, pname, param)
```

### Parameters

`target`

A `GLenum` specifying the binding point (target). Possible values:

* `gl.TEXTURE_2D`: A two-dimensional texture.
* `gl.TEXTURE_CUBE_MAP`: A cube-mapped texture.

When using a WebGL 2 context, the following values are available additionally:

* `gl.TEXTURE_3D`: A three-dimensional texture.
* `gl.TEXTURE_2D_ARRAY`: A two-dimensional array texture.

`param`

 The `param` parameter is a `GLfloat` or
 `GLint` specifying the value for the specified parameter

`pname`

 The `pname` parameter is a `GLenum` specifying the texture
 parameter to set.

| `pname` | Description | `param` |
| --- | --- | --- |
| Available in WebGL 1 |
| --- |
| `gl.TEXTURE_MAG_FILTER` | Texture magnification filter | `gl.LINEAR` (default value), `gl.NEAREST`. |
| `gl.TEXTURE_MIN_FILTER` | Texture minification filter | `gl.LINEAR`, `gl.NEAREST`,
 `gl.NEAREST_MIPMAP_NEAREST`,
 `gl.LINEAR_MIPMAP_NEAREST`,
 `gl.NEAREST_MIPMAP_LINEAR` (default value),
 `gl.LINEAR_MIPMAP_LINEAR`.
  |
| `gl.TEXTURE_WRAP_S` | Wrapping function for texture coordinate `s` | `gl.REPEAT` (default value),`gl.CLAMP_TO_EDGE`,
 `gl.MIRRORED_REPEAT`.
  |
| `gl.TEXTURE_WRAP_T` | Wrapping function for texture coordinate `t` | `gl.REPEAT` (default value),`gl.CLAMP_TO_EDGE`,
 `gl.MIRRORED_REPEAT`.
  |
|
 Additionally available when using the
 `EXT_texture_filter_anisotropic` extension
  |
| `ext.TEXTURE_MAX_ANISOTROPY_EXT` | Maximum anisotropy for a texture | A `GLfloat` value. |
| Additionally available when using a WebGL 2 context |
| `gl.TEXTURE_BASE_LEVEL` | Texture mipmap level | Any int values. |
| `gl.TEXTURE_COMPARE_FUNC` | Texture Comparison function | `gl.LEQUAL` (default value), `gl.GEQUAL`,
 `gl.LESS`, `gl.GREATER`, `gl.EQUAL`,
 `gl.NOTEQUAL`, `gl.ALWAYS`, `gl.NEVER`.
  |
| `gl.TEXTURE_COMPARE_MODE` | Texture comparison mode | `gl.NONE` (default value),
 `gl.COMPARE_REF_TO_TEXTURE`.
  |
| `gl.TEXTURE_MAX_LEVEL` | Maximum texture mipmap array level | Any int values. |
| `gl.TEXTURE_MAX_LOD` | Texture maximum level-of-detail value | Any float values. |
| `gl.TEXTURE_MIN_LOD` | Texture minimum level-of-detail value | Any float values. |
| `gl.TEXTURE_WRAP_R` | Wrapping function for texture coordinate `r` | `gl.REPEAT` (default value), `gl.CLAMP_TO_EDGE`,
 `gl.MIRRORED_REPEAT`.
  |

### Return value

None (`undefined`).

Examples
--------

```js
gl.texParameterf(gl.TEXTURE\_2D, gl.TEXTURE\_MAG\_FILTER, gl.LINEAR);
gl.texParameteri(
  gl.TEXTURE\_2D,
  gl.TEXTURE\_MIN\_FILTER,
  gl.LINEAR\_MIPMAP\_NEAREST,
);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.8 |
| WebGL 2.0 Specification # 3.7.6 |

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

### api.WebGLRenderingContext.texParameterf

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

### api.WebGLRenderingContext.texParameteri

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

See also
--------

* `WebGLRenderingContext.getTexParameter()`
* `EXT_texture_filter_anisotropic`


WebGLRenderingContext: bufferSubData() method - Web APIs

WebGLRenderingContext: bufferSubData() method
=============================================

 The **`WebGLRenderingContext.bufferSubData()`** method of the
 WebGL API updates a subset of a buffer
 object's data store.

Syntax
------

```js
// WebGL1
bufferSubData(target, offset)
bufferSubData(target, offset, srcData)

// WebGL2
bufferSubData(target, dstByteOffset, srcOffset)
bufferSubData(target, dstByteOffset, srcData, srcOffset)
bufferSubData(target, dstByteOffset, srcData, srcOffset, length)
```

### Parameters

`target`

A `GLenum` specifying the binding point (target). Possible values:

`gl.ARRAY_BUFFER`

 Buffer containing vertex attributes, such as
 vertex coordinates, texture coordinate data, or vertex color data.

`gl.ELEMENT_ARRAY_BUFFER`

Buffer used for element indices.

 When using a WebGL 2 context,
 the following values are available additionally:

`gl.COPY_READ_BUFFER`

Buffer for copying from one buffer object to another.

`gl.COPY_WRITE_BUFFER`

Buffer for copying from one buffer object to another.

`gl.TRANSFORM_FEEDBACK_BUFFER`

Buffer for transform feedback operations.

`gl.UNIFORM_BUFFER`

Buffer used for storing uniform blocks.

`gl.PIXEL_PACK_BUFFER`

Buffer used for pixel transfer operations.

`gl.PIXEL_UNPACK_BUFFER`

Buffer used for pixel transfer operations.

`dstByteOffset`

 A `GLintptr` specifying an offset in bytes where the data replacement
 will start.

`srcData` Optional

 An `ArrayBuffer`, `SharedArrayBuffer`, a `DataView`, or a `TypedArray`
 that will be copied into the data store.

`srcOffset`

 A `GLuint` specifying the element index offset where to start reading
 the buffer.

`length` Optional

A `GLuint` defaulting to 0.

### Return value

None (`undefined`).

### Exceptions

* A `gl.INVALID_VALUE` error is thrown if the data would be written past
 the end of the buffer or if `data` is `null`.
* A `gl.INVALID_ENUM` error is thrown if `target` is not one of
 the allowed enums.
Examples
--------

### Using `bufferSubData`

```js
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl");
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY\_BUFFER, buffer);
gl.bufferData(gl.ARRAY\_BUFFER, 1024, gl.STATIC\_DRAW);
gl.bufferSubData(gl.ARRAY\_BUFFER, 512, data);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.5 |

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

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

See also
--------

* `WebGLRenderingContext.createBuffer()`
* `WebGLRenderingContext.bufferData()`
* Other buffers: `WebGLFramebuffer`, `WebGLRenderbuffer`


WebGLRenderingContext: getBufferParameter() method - Web APIs

WebGLRenderingContext: getBufferParameter() method
==================================================

 The **`WebGLRenderingContext.getBufferParameter()`** method of
 the WebGL API returns information about the
 buffer.

Syntax
------

```js
getBufferParameter(target, pname)
```

### Parameters

`target`

A `GLenum` specifying the target buffer object. Possible values:

`gl.ARRAY_BUFFER`

 Buffer containing vertex attributes, such as
 vertex coordinates, texture coordinate data, or vertex color data.

`gl.ELEMENT_ARRAY_BUFFER`

Buffer used for element indices.

 When using a WebGL 2 context,
 the following values are available additionally:

`gl.COPY_READ_BUFFER`

Buffer for copying from one buffer object to another.

`gl.COPY_WRITE_BUFFER`

Buffer for copying from one buffer object to another.

`gl.TRANSFORM_FEEDBACK_BUFFER`

Buffer for transform feedback operations.

`gl.UNIFORM_BUFFER`

Buffer used for storing uniform blocks.

`gl.PIXEL_PACK_BUFFER`

Buffer used for pixel transfer operations.

`gl.PIXEL_UNPACK_BUFFER`

Buffer used for pixel transfer operations.

`pname`

A `GLenum` specifying information to query. Possible values:

`gl.BUFFER_SIZE`

 Returns a `GLint` indicating the size
 of the buffer in bytes.

`gl.BUFFER_USAGE`

 Returns a `GLenum` indicating the
 usage pattern of the buffer. One of the following:

* `gl.STATIC_DRAW`
* `gl.DYNAMIC_DRAW`
* `gl.STREAM_DRAW`

 When using a WebGL 2 context,
 the following values are available additionally:

* `gl.STATIC_READ`
* `gl.DYNAMIC_READ`
* `gl.STREAM_READ`
* `gl.STATIC_COPY`
* `gl.DYNAMIC_COPY`
* `gl.STREAM_COPY`

### Return value

 Depends on the requested information (as specified with `pname`). Either a
 `GLint` or a `GLenum`.

Examples
--------

```js
gl.getBufferParameter(gl.ARRAY\_BUFFER, gl.BUFFER\_SIZE);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.5 |
| WebGL 2.0 Specification # 3.7.3 |

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

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

See also
--------

* `WebGLRenderingContext.bindBuffer()`
* `WebGLRenderingContext.createBuffer()`
* `WebGLRenderingContext.deleteBuffer()`
* `WebGLRenderingContext.bufferData()`
* Other buffers: `WebGLFramebuffer`, `WebGLRenderbuffer`