The suggested fix does not work if the script attaching the shadow root is inline in the page.
For example:
<script>
const shadowHost = document.getElementById('shadow-host');
const shadowRoot = shadowHost.attachShadow({ mode: 'closed' });
...
</script>
the reason is that the script element created in e.g., shadowInject.js in BlackHole's answer, requires the browser to fetch the script and that is done asynchronously, while the script inline in the page is executed immediately as the page loads and therefore the script overrides Element.prototype.attachShadow after it's already been called.
If anyone can think of a solution, here are some of the things I tried and did not work or were not viable solutions for other reasons:
let script = document.createElement('script');
script.innerText = '...hook attachShadow...';
(document.head||document.documentElement).append(script);
this is not a viable solution because it requires unsafe-inline to the CSP and that is the worst possible thing.
Element.attachShadow before it is hooked.It baffles me that in 2024 extensions do not have easy and streamlined access to content inside shadow roots (while devtools does!) and need to resort to this kind of hack. If anyone can think of a way to either gaining access to the DOM content of a shadow root from a chrome extension AFTER it's been created OR alternatively, to ensure Element.attachShadow is hooked before any script can invoke it.... I will be endlessly grateful :)