Bug 50432
Summary: | Web Inspector: inline script blocks and injected script elements don't show "scripts" tab list | ||
---|---|---|---|
Product: | WebKit | Reporter: | Kyle Simpson <getify> |
Component: | Web Inspector (Deprecated) | Assignee: | Nobody <webkit-unassigned> |
Status: | RESOLVED DUPLICATE | ||
Severity: | Minor | CC: | apavlov, bweinstein, joepeck, keishi, loislo, paulirish, pfeldman, pmuellr, rik, yurys |
Priority: | P2 | ||
Version: | 528+ (Nightly build) | ||
Hardware: | All | ||
OS: | All | ||
URL: | http://test.getify.com/webkit-inspector-script-injected/test-1.html |
Kyle Simpson
When an inline script block appears in the markup of a page, or when a script element is created dynamically and injected with script source code (like fetched via XHR), neither of those "scripts" show up in the Webkit Inspector "scripts" tab list. Only external scripts <script src=...> are listed.
While it's true that none of the current browsers I've tested do this, I think it's a little bit of an oversight for such scripts to not be listed and accessible via the Inspector.
The above test has an inline script block, which makes an XHR call, and when (after 5 secs) it returns with script code, a script element is created and added to the DOM and the script code is injected into it. Inspecting the page you'll see that both elements show as DOM elements in the DOM Inspector, but no scripts are listed in the "scripts" tab list.
Attachments | ||
---|---|---|
Add attachment proposed patch, testcase, etc. |
Kyle Simpson
It was noted by @thynctank that JSON-P polling creates lots of script DOM elements, with the potential to make that script list be unmanageably long. Of course, JSON-P script elements aren't of the sort I reported for this bug, but I think it's possible they are also not listed (currently) because they are added well after DOMContentLoaded/onload has passed. Am I correct in that assumption?
In any case, I think whether with JSON-P polling use case or not, stray (or temporary-use) script elements in the DOM should be cleaned up/removed after their purpose is served.
But it brings up the question as to whether or not scripts that have their DOM element removed should also be purged from the list of scripts or not. I can see both sides of the question.
On the one hand, you don't want the list of scripts to become unmanageably long from all those temporary-use script injections. On the other hand, once a script is injected into the page, just removing the element from the DOM does *not* remove it from the JavaScript environment. As such, perhaps those scripts should all stay listed since they are still in scope for the JavaScript context.
Perhaps the best way to handle this is to simply provide a way for the user to change a radio button to select "all", "external", "inline", etc for which scripts should be in shown in the list or filtered from the list. That seems like it might be the easiest way to serve all the use-cases.
Patrick Mueller
You can get "scripts" which otherwise are not shown in the scripts drop-down, to be shown, in Safari, by adding to your script, a comment of the form:
//@sourceURL=name-of-the-script.js
Does not work in Chrome Dev Tools (never did, IIRC).
It should also be the case that if you can get the debugger to stop in one of these un-shown scripts, that while the debugger is stopped there, a script entry is added to the drop-down with the name "(program)".
We tried earlier to just show all the script entries, and for apps that load scripts dynamically (via eval()), the drop-down became a sea of unfriendly "(program)" entries. Be careful what you ask for. :-)
The whole concept of "scripts" in the browser environment is a bit squirrelly to begin with ...
Pavel Feldman
(In reply to comment #2)
> You can get "scripts" which otherwise are not shown in the scripts drop-down, to be shown, in Safari, by adding to your script, a comment of the form:
>
> //@sourceURL=name-of-the-script.js
>
> Does not work in Chrome Dev Tools (never did, IIRC).
>
Wrong. Works for a year or so in Chrome DevTools.
> It should also be the case that if you can get the debugger to stop in one of these un-shown scripts, that while the debugger is stopped there, a script entry is added to the drop-down with the name "(program)".
>
> We tried earlier to just show all the script entries, and for apps that load scripts dynamically (via eval()), the drop-down became a sea of unfriendly "(program)" entries. Be careful what you ask for. :-)
>
> The whole concept of "scripts" in the browser environment is a bit squirrelly to begin with ...
I don't see what's wrong with it. There is a known issue with dynamically added scripts via <script> and document.write that needs to be fixed. There was a nice idea of showing origin of the script (i.e. resource, tag or document.write) that got stuck somewhere half way. We just need to finish it.
Pavel Feldman
> > //@sourceURL=name-of-the-script.js
> >
> > Does not work in Chrome Dev Tools (never did, IIRC).
> >
>
> Wrong. Works for a year or so in Chrome DevTools.
>
But anyways, this is irrelevant to this case both for DevTools and Inspector.
Patrick Mueller
(In reply to comment #3)
> > You can get "scripts" which otherwise are not shown in the scripts drop-down, to be shown, in Safari, by adding to your script, a comment of the form:
> >
> > //@sourceURL=name-of-the-script.js
> >
> > Does not work in Chrome Dev Tools (never did, IIRC).
> >
>
> Wrong. Works for a year or so in Chrome DevTools.
I've pasted a test case below which works differently in Safari and Chrome. In Safari, by the time I hit the debugger statement in "code2", "code1" is now available in the scripts drop-down. In Chrome, it is not available in the scripts drop-down. I tried to investigate this a long time ago (because, again, it's been happening for me for some time), but didn't get very far. It appeared Chrome doesn't go through the same path through the Script class (implemented in JS).
I wonder if you're scanning for a different //@sourceURL= string?
<p>lo
<script>
code1 = [
'// a comment',
'console.log("in code1")',
'//@sourceURL=code1'
].join("\n")
code2 = [
'// a comment',
'debugger',
'console.log("in code2")'
].join("\n")
eval(code1)
eval(code2)
</script>
<p>hi
<!--
Google Chrome: 9.0.597.0 dev
Safari: 5.0.3 (6533.19.4)
-->
Patrick Mueller
(In reply to comment #3)
> > The whole concept of "scripts" in the browser environment is a bit squirrelly to begin with ...
>
> I don't see what's wrong with it. There is a known issue with dynamically added scripts via <script> and document.write that needs to be fixed. There was a nice idea of showing origin of the script (i.e. resource, tag or document.write) that got stuck somewhere half way. We just need to finish it.
Here's the thing. JavaScript source gets injected into the browser in a bunch of ways: <script> tags, onXXX handlers, eval(), Function(), bookmarklets. Looking a little wider, I can use SWT's WebKit interface to run arbitrary JS code from Java - not sure what kind of context that runs under. Etc.
Do we want to show all these little JS bits as separate "scripts". As I mentioned, there were already issues regarding extension (Program) entries when your app loads lots of JS files via XHR (or whatever).
I guess my point is, it's not clear to me that the current way we expose "scripts" - a simple drop down list - really scales to all the places that folks might need it. Perhaps there is a better way. Show scripts in a richer tree-like structure or something like we do other non-trivial collections of things (eg, resources)
Kyle Simpson
would it be possible to do sorta as I suggested above, which is to have a list with different "filters" (like "all", "script", "inline script", "eval", etc) that can filter the list to which sources the user cares about?
Pavel Feldman
Patrick:
- it should be //@ sourceURL, not //@sourceURL.
- Chrome might be not showing code1 in the list since script is collected immediately after execution. I think it is fixed by now.
Naming your evals as suggested at http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/ will work, closing as won't fix. Please feel free to reopen if I missed something.
Kyle Simpson
I am reopening this bug because I still have two issues with how the Webkit inspector currently handles the scripts.
I made this test URL to illustrate:
http://labjs.com/dev/test_suite/inspector/test-LABjs-sourceURL.php?which=1
1. If you load that page with the Inspector closed, and then open Inspector after it finishes loading the scripts, you'll notice something odd (at least it seems odd to me). If you inspect the DOM, you'll see several script elements, for scripts at URLs like so:
http://labjs.xhr.me/dev/test_suite/testscript3.php?delay=1
[inline script]
http://labjs.xhr.me/dev/test_suite/testscript1.php?delay=5
LAB.test.js
However, if you go to the scripts tab, even though "testscript1.php" and "testscript3.php" were in fact loaded with normal (albeit dynamically added) script elements (not eval or injection), they do NOT show up in the list of scripts. Only "LAB.test.js" shows up in the Script tab list.
However, if you have Inspector open while you load the page, "testscript1.php" and "testscript2.php" ARE listed. Then, as soon as you close Inspector and re-open it, the "testscript1.php" and "testscript3.php" are not listed any more. Clearly, these dynamically added scripts are only shown temporarily in Inspector and not persistently, as would seem the expected behavior.
2. I tried to follow the advice of that firebug article, and patched this copy of LABjs (LAB.test.js) to add the //@ sourceURL=... comment to the end of any injected scripts. In this test, "testscript2.php" is loaded via XHR and injected by creating a script element, and setting its .text property.
However, the URL for "testscript2.php" does NOT appear in the Scripts tab list. It would appear that "sourceURL" only works for eval() and not for script injection via .text setting? Or, am I missing something?
You can see in the test that right before it does the script injection, it console.log()'s the last 125 characters of the script its about to inject, and it's definitely including the //@ sourceURL=... comment at the end of what it injects.
Paul Irish
Thanks for the test cases and repro's, Kyle.
*** This bug has been marked as a duplicate of bug 86111 ***