I am embedding some HTML content inside a webpage and I want it to be isolated from outside CSS. My users are able to create HTML content dynamically and these pages can contain some simple JS. I've been trying to run these JS inside a shadow root. Since the JS is created dynamicaly when the user creates the page I need a way to make it possible to run the code inside the shadowroot. I'm adding content as follows:
const header = document.createElement('header');
const shadowRoot = document.createElement('body')
shadowRoot.innerHTML = pageContent
var script = document.createElement('script')
script.textContent = `document.querySelectorAll('#ii0b7a'); document.createElement(........`
shadowRoot.appendChild(script)
header.attachShadow({
mode: 'open'
}).appendChild(shadowRoot)
document.getElementById('div-box-one').appendChild(header)
So far so good, but the code won't run correctly, because the script is accessing the document elements and not the shadowRoot. So I should first access shadowroot and then I'll be able to access the elements inside it. To do so, i'm wrapping the js code inside a function and renaming document variable like this:
(function(document) {
// code here
}(document.getElementById('shadow_root').shadowRoot));
But this approach is not working correctly, because in some case I have to use the function "document.createElement" which will then throw an error.
My question is: How can I rename document variable only when needed. For example
document.querySelectorAll('#') = document.getElementById('shadow_root').shadowRoot.querySelectorAll('#')
document.createElement = document.createElement
I know it is almost impossible to use libraries inside shadowRoot and iframe is another solution, but iframe brings me other problems with it. (shadow-dom library)
Is it possible to achieve what I want renaming somehow the document variable?