How to Get Element in User-Agent Shadow Root With JavaScript

How to read text that is under #shadow-root (user-agent)

As per @hayatoito's (creator of Shadow DOM) comment:

The original motivation of introducing a closed shadow tree is "Never allow an access to a node in a closed shadow tree, via any APIs, from outside", AFAIK. Like that we can not access a node in the internal hidden shadow tree which is used in <video> element, in Blink.

In fact, I designed a closed shadow tree in such a way. If there is a way to access a node in a closed shadow tree, it should be considered as a bug of the spec.

I think it's totally okay to have an API to allow an access in the layer of Chrome apps or extensions.
However, for a normal web app, I think the current agreement is "Never allow it".

If we allowed it, that means we do not need a closed shadow tree. Just having an open shadow tree is enough, I think.

Furhter @Supersharp in his comment below his own answer within the discussion How to get element in user-agent shadow root with JavaScript? mentions:

#shadow-root (user-agent) are browser vendors native implementation so they are not documented and will never be accessible. Only open Shadow DOM are, as per the specs



WebDriver perspective

Recently, @AutomatedTester [David Burns, Chief Bacon Officer, Mozilla Corporation] initiated a discussion on WebDriver - Testability of web components

  • Requests
  • Proposals
  • Issue Tracker

Currently Selenium Team is open for accepting pull requests for the same.



Reference

You can find a couple of relevant detailed discussions in:

  • Need help to click on the element under the shadow Root (closed) type


Outro

Here you can find a relevant discussion on How to automate shadow DOM elements using selenium?

How to get element in user-agent shadow root with JavaScript?

Here is an example:

var container = document.querySelector('#example');
//Create shadow root !
var root = container.createShadowRoot();
root.innerHTML = '<div>Root<div class="test">Element in shadow</div></div>';

//Access the element inside the shadow !
//"container.shadowRoot" represents the youngest shadow root that is hosted on the element !
console.log(container.shadowRoot.querySelector(".test").innerHTML);

Demo:

var container = document.querySelector('#example');//Create shadow root !var root = container.createShadowRoot();root.innerHTML = '<div>Root<div class="test">Element in shadow</div></div>';
//Access the element inside the shadow !console.log(container.shadowRoot.querySelector(".test").innerHTML);
<div id="example">Element</div>

Accessing elements in the shadow DOM

There's no way to access the shadow root of native HTML 5 elements.

Not useful in this case, but with Chrome it's possible to access a custom created shadow root:

var root = document.querySelector("#test_button").createShadowRoot();root.innerHTML = "<button id='inner_button'>Button in button</button"
<button id="test_button"></button>

Is it possible to access Shadow DOM elements through the parent document?

@int32_t is right in that Shadow DOM, by definition, is a way to fill a node with DOM that you want to hide from external sources (Encapsulation). The point is that you as the component author get to choose exactly which parts will be exposed to outside CSS or JavaScript and which will not.

Unfortunately, you cannot create a public JavaScript interface to your Shadow DOM without using another bleeding-edge spec called Custom Elements. If you choose to do that, it's as simple as adding custom public methods to your element's prototype. From these you can access the internals of your Shadow DOM (see the third example here).

You can, however, expose hooks for CSS to access the internals of your Shadow DOM without using Custom Elements. There are two ways to do that:

  1. Pseudo-elements
  2. CSS Variables

Pseudo-elements

Chrome and Firefox expose certain parts of their Shadow DOM to CSS through special pseudo-elements. Here's your example of the date input with the addition of a CSS rule that only applies to the numerical part of the date field through use of the Chrome-provided -webkit-datetime-edit pseudo-element.

Here's a partial list of the available WebKit pseudo-elements. You can also just enable the Show Shadow DOM option in DevTools and look for attributes named pseudo.

Component authors can also create their own pseudo-elements to expose parts of their Shadow DOM (see the 2nd example here).

CSS Variables

An even better way is to use CSS Variables, which you can enable with Enable experimental WebKit features in about:flags in Chrome. Then check out this fiddle which uses CSS Variables to communicate to the Shadow DOM what color it should use for its "theme."

Select shadow div text from page

It's not related to shadow DOM. Following elements are maintaining the value:

<input id="date_release_week" type="text" name="date_release_week" class="filter-options-date date-pick dp-applied hasDatepicker" maxlength="255" autocomplete="off" value="02/02/2022">
<input id="date_begin" type="hidden" name="date_begin" class="filter-options-date-begin" maxlength="255" autocomplete="off" value="02/02/2022">
<input id="date_begin" type="hidden" name="date_begin" class="filter-options-date-begin" maxlength="255" autocomplete="off" value="02/03/2022">

In devtool console if you run one of the following you'll get the actual selected date value:

date_release_week.value
date_begin[0].value
date_begin[1].value

Also, in Jquery, use val() function to get input value: