It's been a long time since we worked on Stack Snippets. I'm sorry. It's mostly because I created it, then I got promoted to management, and now I don't code much anymore and nobody else has time to work on it. So you can blame me.
But before you do blame me, read on for good news!
Thanks in large part to the efforts of canon and his MIT licensed virtual console library for Stack Snippets, we now have a virtual console!
Normally I'd do screenshots, but with Stack Snippets I can just give you a live demo instead. Check it out!
console.log("virtual!");
console.log("console!");
<b>Here's some HTML</b>
The system now offers a new "include console" checkbox in the editor window, which is selected by default. If you hate this new virtual console, you can either unselect it there, or set console: false
in the Stack Snippet markdown. So everybody wins!
Special thanks again to canon who did most of the work on this upgrade!
12 Answers 12
status-completed The console script has been moved to the head and now it waits until DOMContentLoaded
, so console elements are inserted at the end of the body.
The console element should be inserted at the end of the body, just like the script one.
For example, the following code should log Hello!
instead of <div class="as-console"></div>
.
console.log(document.querySelector('div').innerHTML);
<div>Hello!</div>
It seems the problem is in content/Js/snippet-javascript.en.js
'writeResult': function () {
var t = this,
n = t._state.css,
i = t._state.js,
a = t._state.html,
r = t._state.console;
if ('' != n || '' != i || '' != a) {
var o = '';
null != p && (o = '//' + p),
r === !0 && (a = '<script src="' + o + '/scripts/snippet-javascript-console.min.js"></script>' + a);
The last assignment should be
a += '<script src="' + o + '/scripts/snippet-javascript-console.min.js"></script>'
-
-
Now that I think about it,
querySelector
is just the tip of the iceberg. Even if moved to the end, console elements will be affected by CSS and alter the length ofquerySelectorAll
andgetElementsByTagName
collections. The proper way would be moving the user input inside an iframe, and place the console in the outer page.Oriol– Oriol05/22/2016 18:31:25Commented May 22, 2016 at 18:31 -
-
@T.J.Crowder Read up on this and help getting this fixed ASAPuser255093– user25509305/22/2016 19:04:19Commented May 22, 2016 at 19:04
-
1I ran into it in a snippet just yesterday, as I was going to do an example with a series of divs and opened it with
document.querySelectorAll("div")
. Moving it to the end may help some, but then it'll get mixed with any dynamically-added content, and wouldn't have helped in my case yesterday. Having the console div in the same document at all is likely to be an ongoing issue. Think it needs to be moved to a frame.T.J. Crowder– T.J. Crowder05/23/2016 06:33:09Commented May 23, 2016 at 6:33 -
@canon Assuming the iframes have same domain, it would be something like
contentIframe.contentWindow.console.log = function(){ ... }
Oriol– Oriol05/23/2016 16:20:41Commented May 23, 2016 at 16:20 -
@canon I was thinking something like this. But inserting snippet contents at DOMContentLoaded would break snippets which use DOMContentLoaded.Oriol– Oriol05/23/2016 16:55:43Commented May 23, 2016 at 16:55
-
@canon: Thanks for the head's up. FYI: meta.stackexchange.com/questions/279420/…T.J. Crowder– T.J. Crowder05/24/2016 13:39:53Commented May 24, 2016 at 13:39
You cannot XSS using this method, however, the console breaks on HTML style formatting inside a log statement:
console.log("<script>alert('omg');</script>");
-
3@canon must be escaping thingy.
<script></script>
throws, but not<a></a>
.<script></script\>
doesn't throw.Meta Andrew T.– Meta Andrew T.05/18/2016 21:08:21Commented May 18, 2016 at 21:08 -
1Keep in mind there's no huge risk here as-is. We'll get it fixed, but Stack Snippets are sandboxed and secured on a 3rd party domain. Nothing bad will come of anyone's best efforts here. :)05/18/2016 21:14:24Commented May 18, 2016 at 21:14
-
7Instead of putting the code inside of a script tag, you could use
src=
with a data URL (without base64, if you get the encoding right) to avoid this issue. (cc @canon)user1114– user111405/18/2016 23:09:23Commented May 18, 2016 at 23:09 -
3Perhaps this is growing into a new feature request @canon <_<Quill– Quill05/19/2016 04:44:43Commented May 19, 2016 at 4:44
status-completed The console now grows and shrinks with the available width. The box doesn't overflow any more.
The Stack Snippets console overflows on mobile devices if the viewport isn't wide enough.
This is actually just a small layout bug with a wonderful feature. (Thanks Haney!)
The post in the screenshot is this one.
-
4Fixed and live momentarily.05/20/2016 19:13:02Commented May 20, 2016 at 19:13
-
@Pat did you do that when viewing the full site theme, or mobile site theme?user152859– user15285904/03/2017 09:53:31Commented Apr 3, 2017 at 9:53
-
@ShadowWizard mobile viewPatrick Hofman– Patrick Hofman04/03/2017 09:54:49Commented Apr 3, 2017 at 9:54
-
Oh. And now it still works for you?user152859– user15285904/03/2017 09:55:41Commented Apr 3, 2017 at 9:55
-
I can't run the snippet any more @ShaPatrick Hofman– Patrick Hofman04/03/2017 09:57:00Commented Apr 3, 2017 at 9:57
-
@Haney the snippets are not working anymore for mobile, is this on purpose?user152859– user15285904/03/2017 09:57:33Commented Apr 3, 2017 at 9:57
status-completed (this is now implemented and live)
The virtual console currently implements log
, info
, warn
, error
, and clear
, but many other console methods don't write to the virtual console (just the real one):
console.log("This uses the virtual console");
console.dir({o:"testing"}); // This doesn't
console.time("timed"); // This doesn't
console.timeEnd("timed"); // This doesn't
Aggregating data from several DSE queries (because of timeouts; links below), here are the number of questions and answers (combined) in which various console methods occur (roughly), looking only at the javascript and jquery tags:
console.log 287,489 console.error 4,291 console.dir 2,025 console.info 1,940 console.warn 979 console.time 431 console.timeEnd 407 console.clear 277 console.assert 155 console.dirxml 20 console.count 17
Based on that and level of difficulty, I suggest implementing:
dir
as an alias forlog
initially, more can be done if appropriate but the distinction is more for interactive consoles.time
andtimeEnd
, as they're quite easy
It's clearly not feasible to expect that the virtual console will have a union of all of the features offered by Chrome, Firefox, IE, and others! But if it's going to be called console
, I think to minimize surprise we need to ensure it implements the more commonly-used methods.
DSE query links:
-
1@canon: Fantastic! Extremely good of you to take the time to enhance SE in this way. Any idea when they'll put that on the site?T.J. Crowder– T.J. Crowder05/20/2016 17:51:46Commented May 20, 2016 at 17:51
-
1
-
1
Is the date in the log really necessary ?
It doubles the height of a console line and we rarely wait more than 24 hours to see how our snippet behaves (when we do, we lose the fastest gun race and nobody sees our answer so the snippet doesn't really matter).
console.log("virtual!");
console.log("console!");
<b>Here's some HTML</b>
-
4Yeah, good point. I think I'll dump the date part this morning.05/19/2016 13:55:39Commented May 19, 2016 at 13:55
-
3Going live in a few here.05/19/2016 16:36:30Commented May 19, 2016 at 16:36
-
@Haney much cleaner!Denys Séguret– Denys Séguret05/19/2016 19:18:40Commented May 19, 2016 at 19:18
-
-
TBH the time isn't probably useful either...Denys Séguret– Denys Séguret05/20/2016 10:04:09Commented May 20, 2016 at 10:04
-
4Could be, for demonstrating how long something takes.T.J. Crowder– T.J. Crowder05/20/2016 12:11:50Commented May 20, 2016 at 12:11
Move the console outside the document.
Placing the console inside the document can produce lots of interferences. For example:
- CSS selectors like
div
will select console elements - JS collections like
document.querySelectorAll('div')
will include console elements
I think the proper way would be:
- Move the HTML, CSS and JS entered by the user inside an inner content iframe which occupies all the snippet iframe.
- Place the console in the snippet iframe, outside the content iframe
This is how the console behaves in a browser. The content of a page can't interfere with the console.
Here's a simple example of how the console being in the same document is a problem:
console.log("This is...");
setTimeout(function() {
var d = document.createElement('div');
d.appendChild(document.createTextNode("...a problem"));
document.body.appendChild(d);
}, 0);
div {
position: relative !important;
}
<div>Hmmm</div>
Here's another example:
// Demonstration that `length` on the jQuery instance will be 0
// if there are no matching elements. There are no `div` elements
// in this snippet.
$(function() {
console.log($("div").length);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
That demonstration should be logging 0, not 2. Moving the console out of the document entirely is the only way to prevent this kind of cross-talk between the console and the various different snippets people use to demonstrate things.
-
Thanks for reporting this bug. I have modified Stack Snippets to include the console in the
<head>
tag which alleviates DOM assumptions. This fix is now live.05/23/2016 16:06:39Commented May 23, 2016 at 16:06 -
1@Haney Thanks, but that can't work directly. The console script appends some elements to
document.body
, so that will throw an error in the head. Better move the script to the end of the body, or use an event listener in the head.Oriol– Oriol05/23/2016 16:13:29Commented May 23, 2016 at 16:13 -
It has been modified to use an event listener, not to worry!05/23/2016 16:14:32Commented May 23, 2016 at 16:14
-
1@Haney OK, it was a caching problem XDOriol– Oriol05/23/2016 16:16:08Commented May 23, 2016 at 16:16
-
2@Haney: While moving the script is a start, the bigger problem is that the console adds elements to
body
, which interact with the snippet. Have to strongly disagree with the statement that the cost/benefit isn't there. Not only worth doing, but as Oriol points out, it needs doing soon. Here's an example of how it could work: output.jsbin.com/wicofa (Source: main page, console page, example snippet)T.J. Crowder– T.J. Crowder05/24/2016 13:39:25Commented May 24, 2016 at 13:39 -
2@Haney: Sorry, the first JSBin link above is to the wrong page. Here's the example: output.jsbin.com/himaruxT.J. Crowder– T.J. Crowder05/25/2016 06:36:48Commented May 25, 2016 at 6:36
-
4@canon: Great! Can't imagine you need any help, but the offer's there if you like. I know I've said it before, but I'll just say it one last time: I really appreciate your work on this, and I know I'm not the only one who does. It's rubbish that the only reason this is moving forward is that you're doing the work, but it's really great you're doing the work and we're fortunate to have you doing it.T.J. Crowder– T.J. Crowder05/25/2016 23:57:07Commented May 25, 2016 at 23:57
THIS IS NOW IMPLEMENTED IN THE SCRIPT (demo). Just waiting for SE to add a UI for it.
Could we add a flag saying that the console is the entire output? This would do two things:
Let the console fill the result area
Default to not scrolling to the end on ouput (leaving the scrolling up to the user)
In the javascript tag, I post a lot of answers where the console output is the only output of the snippet. In those snippets, all of the Result area other than the virtual console is just wasted space. So how 'bout a "console is result" or similar checkbox:
The default would be off, of course.
Here's an example from this answer — here's the snippet currently in that answer, using my rubbish workaround snippets.js
script:
var str = "j and j and j x";
snippet.log("Search string: '" + str + "'");
for (var n = 0; n < str.length; ++n) {
test(str, n);
}
function test(s, start) {
var index = s.indexOf("j", start);
snippet.log("Starting at " + start + ": " + index);
}
<!-- Script provides the `snippet` object, see https://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
And here it is with the lovely virtual console canon wrote for us:
var str = "j and j and j x";
console.log("Search string: '" + str + "'");
for (var n = 0; n < str.length; ++n) {
test(str, n);
}
function test(s, start) {
var index = s.indexOf("j", start);
console.log("Starting at " + start + ": " + index);
}
As you can see, it shows the end of the output rather than the beginning, a lot more scrolling is required, and clicking the "Full page" link doesn't help.
-
i second that, but i would request a variable splitter, too, because the console output is fixed in size and it would be better if the size can be adjusted.Nina Scholz– Nina Scholz05/20/2016 19:02:12Commented May 20, 2016 at 19:02
-
@NinaScholz: Thanks. I'd post the variable thing as a separate suggestion. This one is just a simple all-or-nothing.T.J. Crowder– T.J. Crowder05/21/2016 06:58:53Commented May 21, 2016 at 6:58
-
I'd love to hear from the downvoters why they don't think this would be useful. I'd be using it every day, several times a day.T.J. Crowder– T.J. Crowder05/21/2016 06:59:21Commented May 21, 2016 at 6:59
-
2@canon: You rock. Yes, normal consoles scroll (well, most do) and we want what you originally did as the default, no question. But the use case for most of my answers is more
document.write
-like, e.g., just output that usually should be read from the top down. (I just refuse to usedocument.write
and lead people into bad habits. :-) ). So yourautoScroll: false
andmaximize
options work perfectly for that. Hope to see a way from SE to use it soon!T.J. Crowder– T.J. Crowder05/21/2016 15:01:45Commented May 21, 2016 at 15:01 -
1@canon: BTW, happy to pitch in if you ever want another pair of hands in there. Just say the word. You clearly don't need the help on a technical level, but everyone has time limitations.T.J. Crowder– T.J. Crowder05/21/2016 15:04:04Commented May 21, 2016 at 15:04
"Show console" (the label on the checkbox for enabling the feature as of the current UI; previously "include console") doesn't say much of anything. I suggest "Use in-snippet console" or similar, with one of those little (i) icons next to it with a fuller sentence.
-
2This makes a lot of sense, gonna spend a few working something more informative up. Thanks!05/20/2016 15:29:44Commented May 20, 2016 at 15:29
-
Done and live in next build.05/20/2016 18:17:38Commented May 20, 2016 at 18:17
-
@Haney: When does that build go live? And will it include a UI for the new options?T.J. Crowder– T.J. Crowder05/28/2016 09:45:09Commented May 28, 2016 at 9:45
-
This idea was recently raised as a standalone question.LWC– LWC03/15/2017 18:58:46Commented Mar 15, 2017 at 18:58
When throwing errors, it would be helpful to actually print the line that the error occurred on, especially as the line mentioned doesn't match up with the source code. Of course, it's good that it shows anything for errors.
console.log('console!!')
console.log([1,2,3])
console.log({i: 'think', this: 'is', cool: '!'})
console.log(console.log)
throw new Error('test')
-
Not only JS-only, but for any error that comes from the JS code, if that's possible.Scimonster– Scimonster05/18/2016 20:24:31Commented May 18, 2016 at 20:24
-
Correct, but here at least we have some measure of control over what it shows. ;)Scimonster– Scimonster05/18/2016 20:32:34Commented May 18, 2016 at 20:32
-
Or instead of adjusting the line number, just give the line of code the error occurred on, as i actually wrote in the answer.Scimonster– Scimonster05/18/2016 20:33:37Commented May 18, 2016 at 20:33
-
This needs more upvotes. :-)T.J. Crowder– T.J. Crowder05/20/2016 16:42:49Commented May 20, 2016 at 16:42
Do not include the console by default, at least until it has been stabilized.
Including the console has collateral effects like Bug in stack snippet?.
People which creates snippets may not realize that this is a bug which (hopefully) will be fixed. So they might rely on the buggy behavior.
Then, once the fix lands, these snippets will break.
Not including the console by default would alleviate this possibility. Moreover, even if the console will be useful to lots of snippets, I think they are still a minority.
Only once the console has been stabilized, it might be considered to enable it by default.
-
2Thanks for reporting this bug. I have modified Stack Snippets to include the console in the
<head>
tag which alleviates DOM assumptions. This fix is now live.05/23/2016 16:06:52Commented May 23, 2016 at 16:06
I can't put a bounty on this answer, so I've raised a formal feature-request instead. If you want this done, please go upvote and or bounty as appropriate.
(削除)
@canon has implemented several useful options in the script (there's a demo here). Please add a UI for them so people don't start using console.config
directly.
I'd suggest making it a Console Options button or some such that shows options driven by the script itself, so that when an option is added to the script, the UI for it can be added at the same time. The options would be serialized to JSON and inserted in the stack snippet's introductory comment node.
For instance, where a snippet might currently start with this:
<!-- begin snippet: js hide: false console: true -->
If the user uses the dialog to set options, it might look like this:
<!-- begin snippet: js hide: false console: true console-options: {"maximize":true,"autoScroll":false} -->
Those options get converted into a hidden call to console.config
at the beginning of the snippet script.
(削除ここまで)
Logging events directly to the console causes the browser to whirrr for a couple of seconds (probably trying to stringify the whole subtree), and throw some errors (in the same console).
Also, it takes a lot longer than necessary to execute the console.log
statement (due to the entire stringification process I guess.)
It currently takes roughly 2-3 seconds for me in Chrome 61. Here's how it looks in the browser console:
function clicked(event) {
var startTime = new Date();
console.log(event);
var endTime = new Date();
console.log("Total time (ms): " + (endTime - startTime));
}
<button onclick="clicked(event)">Click me</button>
-
Almost 16 seconds for meAndrew Myers– Andrew Myers04/10/2018 13:18:34Commented Apr 10, 2018 at 13:18
You must log in to answer this question.
Explore related questions
See similar questions with these tags.
"Mozilla/5.0 (X11; Linux x86_64; rv:48.0) Gecko/20100101 Firefox/48.0"
) but works in Chrome ("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2723.2 Safari/537.36"
). Haven't had time to debug but just quick report.