Skip to content

Component shadow root is not accessible in LWC #1792

Open
@bmblb

Description

@bmblb

Description

I am trying to get current active element inside the web component, but cannot. Maybe this is not a bug but a security measure, regardless I still would appreciate some insight.

Steps to Reproduce

This is not reproducible in playground, I had to use scratch org. Steps:

  1. create new LWC
  2. add this HTML
<template>
    <div class="app slds-p-around_x-large">
        <div class="slds-p-top_large">
            <h2 class="slds-text-heading_medium">Active element</h2>
            <table>
                <tr>
                    <td>activeElement:</td><td>{activeElement}</td>
                </tr>
                <tr>
                    <td>component activeElement:</td><td>{shadowRoot}</td>
                </tr>
            </table>
            <input class="foo" type="text"/>
        </div>
    </div>
</template>
  1. CSS (optional)
h1 {
    color: rgb(0, 112, 210);
}
p {
    font-family: 'Salesforce Sans', Arial, sans-serif;
    color: rgb(62, 62, 60);
}
.app {
    background-color: #fafaf9;
    height: 100vh;
    overflow: scroll;
}
.foo {
    display: block;
}
  1. JS
import { LightningElement } from 'lwc';

export default class Active_element_test extends LightningElement {
    activeElement = '';
    shadowRoot = '';
    listenerSet = false;

    renderedCallback() {
        if (!this.listenerSet) {
            this.listenerSet = true;
            
            const input = this.template.querySelector('.foo');

            const me = this;

            input.addEventListener('focusin', function() {
                me.activeElement = document.activeElement.outerHTML;
                me.shadowRoot = document.activeElement.shadowRoot.activeElement.outerHTML;
            });

            input.addEventListener('focusout', function() {
                me.activeElement = me.shadowRoot = '';
            });
        }
    }
}
  1. meta
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
      <target>lightning__AppPage</target>
    </targets>
</LightningComponentBundle>
  1. Push source to org
  2. Build new lightning app using builder, add this component to the page
  3. Run the app, click input element.

Expected Results

from sandbox
image

Actual Results

image

Browsers Affected

Version

  • @lwc/engine: "1.1.13-224.4"

Additional context/Screenshots
This not a 100% accurate demo, rather a model of my problem. I am trying to utilize 3rd party JS component inside the LWC. It renders a grid with editing capabilities and uses document.activeElement to dive into web components and find real active element:

static get activeElement() {
        let el = document.activeElement;

        while (el.shadowRoot) {
            el = el.shadowRoot.activeElement;
        }

        return el;
    }

As I can see, document.activeElement is a web component element, but it doesn't expose shadow root.
Is that by design? As far as I understood, each web component is supposed to be in own sandbox with patched window/document element, so I wouldn't expect document.activeElement to hide such properties.

Can you suggest any workaround? E.g. if I cannot access document.activeElement, which API can I use in the JS code (loaded through loadScript) to get access to the inner elements of the web component?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions