-
Notifications
You must be signed in to change notification settings - Fork 378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
document.currentScript from a script in a shadow tree. #477
Comments
Per https://html.spec.whatwg.org/multipage/dom.html#dom-document-currentscript,
Wait... As per the definition, I might be wrong. I forgot the case of an event listener. 1 A 'click' event listener is registered in a script in a document tree In this case, it looks that we would violate an encapsulation. |
Hmm. Per the Note:
In the event handler, it looks that document.currentScript should return null, anyway. So it does not violate an encapsulation. Am I correct? |
What about the corresponding events? Also, this would mean that if the executing script does anything within the parent, like call a function, it exposes the shadow tree in a rather trivial matter. |
I see. That would cause an unintentional leak by calling a function such as: var script;
void f() {
script = document.currentScript;
//...
} I thought that we should let DocumentOrShadowRoot have currentScript, however, I am afraid that would not help at all. In most cases, the script needs to get the script element without any reference to its shadow root. |
That is a very good point, the script does not really know where it is, that is why we have this feature in the first place. Maybe it's okay to have this and scripts just need to be careful. This is no isolation after all. The events would still be troublesome however, but only Firefox implements those at the moment. @smaug----, thoughts? |
The outer world shouldn't know there is a shadow script being executed so document.currentScript should never point to a shadow <script>. And the events should be scoped. I don't see any good way to support currentScript for shadow scripts, unless we execute shadow scripts somehow in a special scope where shadowCurrentScript or some such is explicitly exposed. (yet another case where I think XBL2 had things right) |
@smaug---- it only points to the script while the script is executing though, no? So how can the outer world observe it? |
Also, what kind of feature would give the shadow script a pointer to itself? |
Just what was explained earlier. Shadow script calling some non-shadow function which accesses document.currentScript. That is accidental exposure, and it can happen when explicitly calling non-shadow functions or dispatching events from shadow script and handling them elsewhere. |
So what is your solution? |
Hmm, but that brings in another question. What should happen to the variables defined in shadow scripts. Perhaps we should actually execute those scripts inside some anonymous scope. |
My current solution is to not expose shadow-script elements in document.currentScript and making events scoped. And let scripts to live with that limitation. |
I understand the point. However, I am afraid that we are worrying too much about this kind of exposure. For me, it sounds "document.currentScript" is something like a thread-local variable. We do not have to stress on It's difficult to decide where we should draw the line. However, in this particular case, I think it's okay that we have a global function which returns the script element which is currently running. Due to the historical reason, this global function is defined in a "document". I'm okay to restrict document.currentScript, however, we need an alternative global function for a script in a shadow tree, such as My preferences: [Preferred]
|
Worrying about escape via shadow scripts calling non-shadow scripts seems similar to the many worries people have about closed shadow roots not being closed enough. (E.g., you can modify the running of script in those by overriding getters or setters on |
What are use cases in which scripts inside a shadow DOM would need to use Until such use cases are presented, I'd assume such a feature is not needed. So I support option 3 since adding such a feature retroactively or reverting the behavior back to option 1 is easy while shipping option 1 today and changing it later to option 2 or option 3 would be backwards incompatible. |
The use case for a script in a shadow tree should be the same to a use case for a script in a document tree. Is there any difference between them? |
@hayatoito what are those use cases? |
document.currentScript.ownerDocument ? (as far as I spotted in the past...) It looks there are a lot of other use cases, per http://stackoverflow.com/search?q=document.currentScript |
I'm not certain things listed there would apply to shadow DOM. For example, http://stackoverflow.com/questions/32466974/using-document-currentscript-to-append-data-to-divs talks about appending data using attributes specified in the script element. Since there is no declarative syntax for shadow DOM, this wouldn't be a useful technique in practice. It would be much better to do the work using a custom element in the new web components world. http://stackoverflow.com/questions/24986178/get-script-element-in-dom-tree/24986240, again, talks about loading JSON data from the server and generating a table out of it. That just doesn't happen with shadow DOM which lacks declarative syntax at the moment. Even if you had a declarative syntax, you wouldn't put data and script inside a shadow tree. You'd instead use a custom element with data inside of it, and then use http://stackoverflow.com/questions/19936425/dynamically-create-iframe-and-append-to-unknown-parent/19939766 is about creating an iframe when a script is loaded. Again, there is no need to insert a script element, then have it insert an iframe when creating a shadow tree. You should just do that upfront when you're creating a shadow tree. Alternatively, use a custom element to do it. This post about "protecting" a JS object seems completely misguided: http://stackoverflow.com/questions/32739099/protecting-a-javascript-object-against-external-scripts/32739197 I don't think http://stackoverflow.com/questions/35608095/having-the-same-widget-on-a-page-multiple-time-variable-clashes/35608462#35608462 is anything to do with having to use http://stackoverflow.com/questions/403967/how-may-i-reference-the-script-tag-that-loaded-the-currently-executing-script/3695686 is about on-demand loading of other scripts within a I've looked at a few other posts listed there but I don't think any of them benefit the use inside a shadow tree. They're either useless or actively harmful inside a shadow tree. |
We would we let document.currentScript to return anything in shadow DOM when we don't let event.target to do that. And in case of event dispatching, shadow script doesn't need to call To be honest, I'm rather surprised anyone even questions the ''document.currentScript shouldn't return shadow script elements." |
@smaug---- isn't |
That is quite different. event isn't any global object, so one needs to explicitly pass event in that state to some light DOM function. And no need to use deepPath() there. light DOM could just use event.currentTarget, or shadow listener could just pass some node to light dom function. |
@smaug---- quite a few implementations have |
I would expect window.event to be null when event.currentTarget points to some shadow DOM node. |
I'm wondering how a script in a shadow tree can access its root node (DocumentOrShadowRoot), if there is no way to access the script element. If they can get the script element, they can access the root node easily, via currentScipt.rootNode, where a lot of useful APIs are available. Thus, I'm wondering that |
The use cases for this are the same for the main document, ex. reading data off the
if you appendChild that to your shadowRoot, document.currentScript is needed for the script to be able to read back option attributes. I don't think we can invent a new or fancier context aware property, that requires tagging every function to see what script created it. |
[Sorry I had verbiage here about the context of The issue if I understand it then is primarily dispatching an event from shadow-root? IMO, the leakage risk is less worrisome than unintended consequences of changing the behavior of |
Again, I don't think that's a useful thing to do inside a shadow DOM since that would mean that every instance of such a shadow DOM would try to fetch the script. Unless the script is cached and doesn't require validation, it would end up issuing a network request each time. A better approach would be using a custom element. |
I support not restricting this in any way (it may be a source of closed shadow root leakage, but that is not really a problem). |
Telecon consensus: return null always (both open and closed shadow trees) |
See also whatwg/html#997. We also discussed the desire for a new API in modules that introduces some kind of currentScript variable into the module scope, but doesn't put it on the global which everyone can access. |
I'm adding a test for this in web-platform-tests/wpt#2934. |
So the alternate proposal My need is not really the get the Maybe there's a best approach that I missed (apart from using customized built-in elements... when they are implemented). |
+1 on accessing the shadow dom from a script node. How do you propose to do something like this <template id="component">
<div id="some-div"></div>
<link href="/static/css/main.cacbacc7.css" rel="stylesheet">
<script src="/static/js/bundle.js" type="text/javascript"></script>
</template> bundle.js const myDom = window.currentScript.ownerDocument.querySelector('#some-div'); |
If there's any chance to catch the |
Also, a good idea is to have something like document.querySelector('#myshadowroot').defined.then(currentShadowRoot => {
}); In the same fashion as custom elements |
Continuing discussion in the closed thread may not get attention from people. |
There's no need for a new issue, this is tracked by whatwg/html#1013. |
I'm sorry if I miss something. From reading this discussion I cannot see why Consider the element: customElements.define('expose-shadow-root',class extends HTMLElement{
connectedCallback(){
window.exposeShadowRoot = this.getRootNode();
}
}) Then in putting <script>
document.currentScript.getRootNode().getElementById('horn').addEventListener('click',()=>{alert('beep')});
</script> However, non-violating use of In my opinion as long as there is no JS encapsulation for custom elements, exposing shadow root programmatically will always be trivial. Yes, I know I can define and create an instance of a custom element instead of this script, but that's like using sledgehammer to crack a peanut. |
You can leak the shadow tree yourself, but if we provide platform APIs that leak the shadow tree it's just bad news. |
How does platform API leaks itself? I put |
Regarding #377,
I thought that document.currentScript should return null if a running script is in a shadow tree,
however, given that "document.currentScript" is always executed by the script, this situation looks like : "the script is just accessing the script element which is running me".
It's like a this pointer... This does not seem to violate an encapsulation.
Thus, what document.currentScript should be? Is it okay to return a script element in a shadow tree?
The text was updated successfully, but these errors were encountered: