2

I'm trying to detect if an extension is installed by checking if it adds a specific div inside the body.

When the extension is installed it adds the following div in the end of the body:

<div>
  #shadow-root (closed)
    <div id="extension_name">
      <!--div content here-->
    </div>
</div>

Is there a way to detect this element with a simple document query like:

document.body.queryselector(':shadow-root #extension-name')

If not, any suggestion about an efficient way to check if this element exists?

Felipe César
  • 1,234
  • 2
  • 16
  • 34
  • 1
    If the extension created the element in its content script (i.e. not in [page context](/a/9517879)) then there's no way for the page to peek into a closed shadow root. In case of page context, it depends on timing: if the extension doesn't safe-guard itself against spoofing then you can hook Element.prototype.attachShadow. – wOxxOm Feb 11 '21 at 20:19
  • 1
    If you attach a shadow root to a custom element with mode: closed set, you won't be able to access the shadow DOM from the outside [MDN](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM#basic_usage) – Louys Patrice Bessette Feb 11 '21 at 20:19

2 Answers2

1

So looks like it's impossible to get the information when the shadow dom is closed. So I had to find alternative ways to detect the extension.

When it's open we can query using:

const isInstalled = Array.from(window.document.body.children).reverse().find(
  (item) => item.localName === 'div' && item.shadowRoot !== null && item.shadowRoot.querySelector('#extension_name')
) !== undefined;

Ps: Most of the extensions append the div on the end of the body. So reverse is intended to optimize the query.

Thanks @wOxxOm and @Louys Patrice Bessette for the help.

Felipe César
  • 1,234
  • 2
  • 16
  • 34
0

Your code:

  • doesn't detect when there are multiple/nested shadowRoots

  • doesn't detect when any of those is a closed shadowRoot

instead

  • Make you component listen at document level for a extension_name Event

  • Let your testcode dispatch a extension_name Event

You can even pass a function in event.detail and let your extension execute it

Danny '365CSI' Engelman
  • 16,526
  • 2
  • 32
  • 49