Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs for shadow root serializable property (everywhere) #33600

Merged
merged 8 commits into from
May 17, 2024
6 changes: 6 additions & 0 deletions files/en-us/web/api/element/attachshadow/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ attachShadow(options)
- : A boolean that, when set to `true`, specifies behavior that mitigates custom element issues around focusability.
When a non-focusable part of the shadow DOM is clicked, the first focusable part is given focus, and the shadow host is given any available `:focus` styling. Its default value is `false`.

- `serializable` {{Optional_Inline}}

- : A boolean that, when set to `true`, indicates that the shadow root is serializable.
If set, the shadow root may be serialized by calling the {{DOMxRef('Element.getHTML()')}} or {{DOMxRef('ShadowRoot.getHTML()')}} methods with the `options.serializableShadowRoots` parameter set `true`.
Its default value is `false`.

- `slotAssignment` {{Optional_inline}}

- : A string specifying the _slot assignment mode_ for the shadow DOM tree. This can be one of:
Expand Down
17 changes: 13 additions & 4 deletions files/en-us/web/api/element/gethtml/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ browser-compat: api.Element.getHTML

The **`getHTML()`** method of the {{domxref("Element")}} interface is used to serialize an element's DOM to an HTML string.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved

The method provides an options argument that enables the serialization of child nodes that are shadow roots.
The options can be used to include nested shadow roots that have been set as {{domxref("ShadowRoot/serializable","serializable")}}, and/or a specified array of {{domxref("ShadowRoot")}} objects, which may be either open or closed.

Without arguments, child nodes that are shadow roots are not serialized, and this method behaves in the same way as reading the value of {{domxref("Element.innerHTML")}}.

## Syntax

```js-nolint
const html = element.getHTML(options)
getHTML(options)
```

### Parameters
Expand All @@ -25,10 +30,12 @@ const html = element.getHTML(options)
- : An options object with the following optional parameters:

- `serializableShadowRoots`
- : A boolean value that specifies whether to include serializable shadow roots. The default value is `false`.
- : A boolean value that specifies whether to include {{domxref("ShadowRoot/serializable","serializable")}} shadow roots.
The default value is `false`.
- `shadowRoots`
- : An array of {{domxref("ShadowRoot")}} objects to serialize. These are included regardless of whether they
are marked as serializable. The default value is an empty array.
- : An array of {{domxref("ShadowRoot")}} objects to serialize.
These are included regardless of whether they are marked as `serializable`, or if they are open or closed.
The default value is an empty array.

### Return value

Expand All @@ -50,3 +57,5 @@ None.

- {{domxref("ShadowRoot.getHTML()")}}
- {{domxref("Element.innerHTML")}}
- {{domxref("Element.setHTMLUnsafe()")}}
- {{domxref("ShadowRoot.setHTMLUnsafe()")}}
58 changes: 27 additions & 31 deletions files/en-us/web/api/element/innerhtml/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,45 +8,44 @@ browser-compat: api.Element.innerHTML

{{APIRef("DOM")}}

The {{domxref("Element")}} property
**`innerHTML`** gets or sets the HTML or XML markup contained
within the element.
The {{domxref("Element")}} property **`innerHTML`** gets or sets the HTML or XML markup contained within the element.

To insert the HTML into the document rather than replace the contents of an element,
use the method {{domxref("Element.insertAdjacentHTML", "insertAdjacentHTML()")}}.
More precisely, `innerHTML` gets a serialization of the nested child DOM elements within the element, or sets HTML or XML that should be parsed to replace the DOM tree within the element.

To insert the HTML into the document rather than replace the contents of an element, use the method {{domxref("Element.insertAdjacentHTML", "insertAdjacentHTML()")}}.

The serialization of the DOM tree read from the property does not include {{glossary("shadow tree", "shadow roots")}} — if you want to get a HTML string that includes shadow roots, you must instead use the {{domxref("Element.getHTML()")}} or {{domxref("ShadowRoot.getHTML()")}} methods.
Similarly, when setting element content using `innerHTML`, the HTML string is parsed into DOM elements that does not contain shadow roots.
sideshowbarker marked this conversation as resolved.
Show resolved Hide resolved

So for example [`<template>`](/en-US/docs/Web/HTML/Element/template) is parsed into as {{domxref("HTMLTemplateElement")}}, whether or not the [`shadowrootmode`](/en-US/docs/Web/HTML/Element/template#shadowrootmode) attribute is specfied
In order to set an element's contents from an HTML string that includes declarative shadow roots, you must use either {{domxref("Element.setHTMLUnsafe()")}} or {{domxref("ShadowRoot.setHTMLUnsafe()")}}.
sideshowbarker marked this conversation as resolved.
Show resolved Hide resolved

## Value

A string containing the HTML serialization of the element's
descendants. Setting the value of `innerHTML` removes all of the element's
descendants and replaces them with nodes constructed by parsing the HTML given in the
string _htmlString_.
A string containing the HTML serialization of the element's descendants.
Setting the value of `innerHTML` removes all of the element's descendants and replaces them with nodes constructed by parsing the HTML given in the string _htmlString_.

### Exceptions

- `SyntaxError` {{domxref("DOMException")}}
- : Thrown if an attempt was made to set the value of `innerHTML` using a string which
is not properly-formed HTML.
- : Thrown if an attempt was made to set the value of `innerHTML` using a string which is not properly-formed HTML.
- `NoModificationAllowedError` {{domxref("DOMException")}}
- : Thrown if an attempt was made to insert the HTML into a node whose parent is a
{{domxref("Document")}}.
- : Thrown if an attempt was made to insert the HTML into a node whose parent is a {{domxref("Document")}}.

## Usage notes

The `innerHTML` property can be used to examine the current HTML source of the page, including any changes that have been made since the page was initially loaded.
sideshowbarker marked this conversation as resolved.
Show resolved Hide resolved

### Reading the HTML contents of an element

Reading `innerHTML` causes the user agent to serialize the HTML or XML fragment comprised of the element's descendants. The resulting string is returned.
Reading `innerHTML` causes the user agent to serialize the HTML or XML fragment comprised of the element's descendants.
The resulting string is returned.

```js
let contents = myElement.innerHTML;
```

This lets you look at the HTML markup of the element's content nodes.

> **Note:** The returned HTML or XML fragment is generated based on the current contents of the element, so the markup and formatting of the returned fragment
> is likely not to match the original page markup.
> **Note:** The returned HTML or XML fragment is generated based on the current contents of the element, so the markup and formatting of the returned fragment is likely not to match the original page markup.

### Replacing the contents of an element

Expand Down Expand Up @@ -78,10 +77,8 @@ document.documentElement.innerHTML = `<pre>${document.documentElement.innerHTML.
What exactly happens when you set value of `innerHTML`?
Doing so causes the user agent to follow these steps:

1. The specified value is parsed as HTML or XML (based on the document type),
resulting in a {{domxref("DocumentFragment")}} object representing the new set of DOM nodes for the new elements.
2. If the element whose contents are being replaced is a {{HTMLElement("template")}} element,
then the `<template>` element's {{domxref("HTMLTemplateElement.content", "content")}} attribute is replaced with the new `DocumentFragment` created in step 1.
1. The specified value is parsed as HTML or XML (based on the document type), resulting in a {{domxref("DocumentFragment")}} object representing the new set of DOM nodes for the new elements.
2. If the element whose contents are being replaced is a {{HTMLElement("template")}} element, then the `<template>` element's {{domxref("HTMLTemplateElement.content", "content")}} attribute is replaced with the new `DocumentFragment` created in step 1.
3. For all other elements, the element's contents are replaced with the nodes in the new `DocumentFragment`.

### Appending HTML to an element
Expand Down Expand Up @@ -127,12 +124,9 @@ name = "<script>alert('I am John in an annoying alert!')</script>";
el.innerHTML = name; // harmless in this case
```

Although this may look like a [cross-site scripting](https://en.wikipedia.org/wiki/Cross-site_scripting)
attack, the result is harmless. HTML specifies that a {{HTMLElement("script")}} tag
inserted with `innerHTML` [should not execute](https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml0).
Although this may look like a [cross-site scripting](https://en.wikipedia.org/wiki/Cross-site_scripting) attack, the result is harmless. HTML specifies that a {{HTMLElement("script")}} tag inserted with `innerHTML` [should not execute](https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml0).

However, there are ways to execute JavaScript without using {{HTMLElement("script")}} elements,
so there is still a security risk whenever you use `innerHTML` to set strings over which you have no control.
However, there are ways to execute JavaScript without using {{HTMLElement("script")}} elements, so there is still a security risk whenever you use `innerHTML` to set strings over which you have no control.
For example:

```js
Expand Down Expand Up @@ -167,12 +161,10 @@ function log(msg) {
log("Logging mouse events inside this container…");
```

The `log()` function creates the log output by getting the current time from a {{jsxref("Date")}} object using
{{jsxref("Date.toLocaleTimeString", "toLocaleTimeString()")}}, and building a string with the timestamp and the message text.
The `log()` function creates the log output by getting the current time from a {{jsxref("Date")}} object using {{jsxref("Date.toLocaleTimeString", "toLocaleTimeString()")}}, and building a string with the timestamp and the message text.
Then the message is appended to the box with the class `"log"`.

We add a second method that logs information about {{domxref("MouseEvent")}} based events
(such as {{domxref("Element/mousedown_event", "mousedown")}}, {{domxref("Element/click_event", "click")}}, and {{domxref("Element/mouseenter_event", "mouseenter")}}):
We add a second method that logs information about {{domxref("MouseEvent")}} based events (such as {{domxref("Element/mousedown_event", "mousedown")}}, {{domxref("Element/click_event", "click")}}, and {{domxref("Element/mouseenter_event", "mouseenter")}}):

```js
function logEvent(event) {
Expand Down Expand Up @@ -249,3 +241,7 @@ You can see output into the log by moving the mouse in and out of the box, click
- {{domxref("Element.outerHTML")}}
- Parsing HTML or XML into a DOM tree: {{domxref("DOMParser")}}
- Serializing a DOM tree into an XML string: {{domxref("XMLSerializer")}}
- {{domxref("Element.getHTML()")}}
- {{domxref("ShadowRoot.getHTML()")}}
- {{domxref("Element.setHTMLUnsafe()")}}
- {{domxref("ShadowRoot.setHTMLUnsafe()")}}
2 changes: 2 additions & 0 deletions files/en-us/web/api/htmltemplateelement/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ _This interface inherits the properties of {{domxref("HTMLElement")}}._
- : A boolean that reflects the value of the [`shadowrootdelegatesfocus`](/en-US/docs/Web/HTML/Element/template#shadowrootdelegatesfocus) attribute of the associated `<template>` element.
- {{domxref("HTMLTemplateElement.shadowRootClonable", "shadowRootClonable")}}
- : A boolean that reflects the value of the [`shadowrootclonable`](/en-US/docs/Web/HTML/Element/template#shadowrootclonable) attribute of the associated `<template>` element.
- {{domxref("HTMLTemplateElement.shadowRootSerializable", "shadowRootSerializable")}}
- : A boolean that reflects the value of the [`shadowrootserializable`](/en-US/docs/Web/HTML/Element/template#shadowrootserializable) attribute of the associated `<template>` element.

## Instance methods

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: "HTMLTemplateElement: shadowRootSerializable property"
short-title: content
slug: Web/API/HTMLTemplateElement/shadowRootSerializable
page-type: web-api-instance-property
browser-compat: api.HTMLTemplateElement.shadowRootSerializable
---

{{APIRef("Web Components")}}

The **`shadowRootSerializable`** property reflects the value of the [`shadowrootserializable`](/en-US/docs/Web/HTML/Element/template#shadowrootserializable) attribute of the associated [`<template>`](/en-US/docs/Web/HTML/Element/template) element.

Note that this property is not useful for developers.
If a `<template>` element is used to declaratively create a [`ShadowRoot`](/en-US/docs/Web/API/ShadowRoot), then this object and property do not exist.
Otherwise, if an `HTMLTemplateElement` is created, the value of this property is irrelevant because the object is not a shadow root and cannot subsequently be changed to a shadow root.

## Value

Reflects the value of the [`shadowrootserializable`](/en-US/docs/Web/HTML/Element/template#shadowrootserializable) attribute of the associated [`<template>`](/en-US/docs/Web/HTML/Element/template) element.

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- [`shadowrootserializable`](/en-US/docs/Web/HTML/Element/template#shadowrootserializable) attribute of the `<template>` element
- [`ShadowRoot.serializable`](/en-US/docs/Web/API/ShadowRoot/serializable)
18 changes: 14 additions & 4 deletions files/en-us/web/api/shadowroot/gethtml/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ browser-compat: api.ShadowRoot.getHTML

The **`getHTML()`** method of the {{domxref("ShadowRoot")}} interface is used to serialize a shadow root's DOM to an HTML string.

The method provides an options argument that enables the serialization of child nodes that are shadow roots.
The options can be used to include nested shadow roots that have been set as {{domxref("ShadowRoot/serializable","serializable")}}, and/or a specified array of {{domxref("ShadowRoot")}} objects, which may be either open or closed.

Without arguments, child nodes that are shadow roots are not serialized, and this method behaves in the same way as reading the value of {{domxref("Element.innerHTML")}}.

## Syntax

```js-nolint
Expand All @@ -25,10 +30,12 @@ const html = shadowRoot.getHTML(options)
- : An options object with the following optional parameters:
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved

- `serializableShadowRoots`
- : A boolean value that specifies whether to include serializable shadow roots. The default value is `false`.
- : A boolean value that specifies whether to include [serializable](/en-US/docs/Web/API/ShadowRoot/serializable) shadow roots.
The default value is `false`.
- `shadowRoots`
- : An array of {{domxref("ShadowRoot")}} objects to serialize. These are included regardless of whether they
are marked as serializable. The default value is an empty array.
- : An array of {{domxref("ShadowRoot")}} objects to serialize.
These are included regardless of whether they are marked as `serializable`, or if they are open or closed.
The default value is an empty array.

### Return value

Expand All @@ -48,4 +55,7 @@ None.

## See Also

- {{domxref("ShadowRoot.innerHTML")}}
- {{domxref("Element.getHTML()")}}
- {{domxref("Element.innerHTML")}}
- {{domxref("ShadowRoot.setHTMLUnsafe()")}}
- {{domxref("Element.setHTMLUnsafe()")}}
8 changes: 6 additions & 2 deletions files/en-us/web/api/shadowroot/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ You can retrieve a reference to an element's shadow root using its {{domxref("El
- : Add an array of constructed stylesheets to be used by the shadow DOM subtree.
These may be shared with other DOM subtrees that share the same parent {{domxref("Document")}} node, and the document itself.
- {{domxref("ShadowRoot.clonable")}} {{ReadOnlyInline}}
- : Returns a boolean that indicates whether the shadow root is clonable, which can be set via the {{domxref("Element.attachShadow()")}} `clonable` option.
- : A boolean that indicates whether the shadow root is clonable.
- {{domxref("ShadowRoot.delegatesFocus")}} {{ReadOnlyInline}}
- : Returns a boolean that indicates whether `delegatesFocus` was set when the shadow was attached (see {{domxref("Element.attachShadow()")}}).
- : A boolean that indicates whether the shadow root delegates focus if a non-focusable node is selected.
- {{DOMxRef("ShadowRoot.fullscreenElement")}} {{ReadOnlyInline}}
- : The element that's currently in full screen mode for this shadow tree.
- {{domxref("ShadowRoot.host")}} {{ReadOnlyInline}}
Expand All @@ -38,6 +38,10 @@ You can retrieve a reference to an element's shadow root using its {{domxref("El
- {{DOMxRef("ShadowRoot.pointerLockElement")}} {{ReadOnlyInline}}
- : Returns the {{DOMxRef('Element')}} set as the target for mouse events while the pointer is locked.
`null` if lock is pending, pointer is unlocked, or if the target is in another tree.
- {{DOMxRef("ShadowRoot.serializable")}} {{ReadOnlyInline}}
- : A boolean that indicates whether the shadow root is serializable.
A serializable shadow root inside an element will be serialized by {{DOMxRef('Element.getHTML()')}} or {{DOMxRef('ShadowRoot.getHTML()')}} when its [`options.serializableShadowRoots`](/en-US/docs/Web/API/Element/getHTML#serializableshadowroots) parameter is set `true`.
This is set when the shadow root is created.
- {{DOMxRef("ShadowRoot.slotAssignment")}} {{ReadOnlyInline}}
- : Returns a string containing the type of slot assignment, either `manual` or `named`.
- {{domxref("ShadowRoot.styleSheets")}} {{ReadOnlyInline}}
Expand Down
39 changes: 39 additions & 0 deletions files/en-us/web/api/shadowroot/serializable/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: "ShadowRoot: serializable property"
short-title: serializable
slug: Web/API/ShadowRoot/serializable
page-type: web-api-instance-property
browser-compat: api.ShadowRoot.serializable
---

{{APIRef("Shadow DOM")}}

The **`serializable`** read-only property of the {{domxref("ShadowRoot")}} interface returns `true` if the shadow root is serializable.

If set, the shadow root may be serialized by calling the {{DOMxRef('Element.getHTML()')}} or {{DOMxRef('ShadowRoot.getHTML()')}} methods with the `options.serializableShadowRoots` parameter set `true`.

The serializable property of a shadow root is specified when the shadow root is created, either declaratively by adding the [`shadowrootserializable`](/en-US/docs/Web/HTML/Element/template#shadowrootserializable) attribute on a `<template>` element (along with an allowed [`shadowrootmode`](/en-US/docs/Web/HTML/Element/template#shadowrootmode) value), or by setting the [`options.serializable`](/en-US/docs/Web/API/Element/attachShadow#serializable) parameter to `true` when using [`Element.attachShadow()`](/en-US/docs/Web/API/Element/attachShadow).

## Value

`true` if the shadow root is serializable; `false` otherwise.

## Examples

```js
let customElem = document.querySelector("my-shadow-dom-element");
let shadow = customElem.shadowRoot;

// ...

// Is it serializable?
let hostElem = shadow.serializable;
```

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}
Loading