whatwg / console Goto Github PK
View Code? Open in Web Editor NEWConsole Standard
Home Page: https://console.spec.whatwg.org/
License: Other
Console Standard
Home Page: https://console.spec.whatwg.org/
License: Other
See e.g. https://fetch.spec.whatwg.org/#acknowledgments or https://streams.spec.whatwg.org/#acks
This is actually pretty important since that is where the CC0 declaration goes.
#38 and the related Firefox fix could maybe be called out more explicitly in the spec. I would suggest a non-normative NOTE something like this, after the Logger algorithm.
It's important here that the printing occurs before returning from the algorithm. Many developer consoles print the result of the last operation entered into them. In such consoles, when a developer enters
console.log("hello!")
, this should first print"hello!"
, then theundefined
return value from theconsole.log
call.
You could even include an example screenshot showing this behavior.
#60 discusses an issue with the current spec for console.count(), which says
Perform Logger("log", concat).
But given code like
console.count("a");
console.count("a");
implementations will generally not log
a: 1
a: 2
but instead will update the first line to say "a: 2".
Now, since Printer (called by Logger) is implementation defined, the spec actually allows this just fine. But it's pretty unclear. It's also a bit strange since we do Logger("log", concat)
, so the implementation would have to use some out-of-band magic to remember that this "log"
is not the same as console.log()
s "log"
.
Personally I think the best fix would be:
Node.js behaves a bit differently for console.assert()
as specified in the docs:
There is even this note: Note: the console.assert() method is implemented differently in Node.js than the console.assert() method available in browsers.
.
Note: console.assert()
was added in Node v0.1.101. Changing it may be difficult.
I guess I can do this since I think only admins have permission to change webhooks.
(Forking this from discussion in #27)
Chrome's implementation right now is:
%o
- display using the user agent's default formatting for that object type. For example: console.log('%o', obj)
is identical to console.log(obj)
.%O
- display as a javascript object. For example: console.log('%O', obj)
is identical to console.dir(obj)
.Currently, Chrome logs elements as a tree (dirxml-style), but we plan to change that very soon (to log them as objects (dir-style). As a result, %o
will change because it just follows our default formatting. There is currently no format specifier to force dirxml-style logging of objects. (source: _formatWithSubstitutionString
)
%o
is a generalized specifier for all js objects. It will use whatever formatter we think is best. They can be one of the following: array, error, function, generator, iterator, map, node, object, set, string
. (source: _customFormatters
)
Here's the difference of %o
and %O
on an array:
This is an extension of #26 where @domenic and I discussed implementation differences regarding console.time/timeEnd
.
With count there are two things to test (similarly to time):
label = ""
console.count()
and console.count(undefined)
not only work, but also produce identical resultsToString()
conversion is being delegated to
label.toString()
gets called if the count label
is an object.count()
behaves differently than count(undefined)
.
count()
uses label "no label" instead of "default"
count(undefined)
uses label "undefined"
instead of "default"
label.toString()
when label is object.count()
behaviorcount()
behaves differently than count(undefined)
.
count()
uses label ""
instead of "default"
count(undefined)
uses label "undefined"
instead of "default"
label.toString()
ever (just like time
)time
may incidentally fix count
!count()
uses label ""
instead of "default"
label.toString()
when label is object.count()
behaviorcount()
behaves differently than count(undefined)
count()
uses label "Global" instead of "default"
count(undefined)
uses label "undefined"
instead of "default"
label.toString()
when label is object.count()
behaviorI think this is quite a bit worse than time
, however a lot of the non-compliant behavior revolves around differing default labels on count()
and the fact that count(undefined)
converted undefined
=> "undefined"
as a string. Does it make sense to do something similar to what the recent changes to assert
are doing, in that we can make the label
optional with no default value, and in the algorithm suggest a default value but allow implementations to choose what they see fit. This may help compliancy out a bit, but we'll still need to open bugs for undefined
=> "undefined"
.
Regarding web platform tests for this, are we limited to visual tests since we cannot (to my knowledge) programmatically check to see what value a console did/didn't log after some call?
Right now assigning a console function to a local variable kind of sucks, since they're expected to be called within the context of console
. This requires the developer to bind.
var log = console.log.bind(console);
log('\(゜ロ\)ココハドコ? (/ロ゜)/アタシハダアレ?');
Except this doesn't work in some versions of IE because the console functions aren't instances of Function!
var log = Function.prototype.bind.call(console.log, console);
log('(ノಠ益ಠ)ノ彡┻━┻');
Which is a lot to type for a pretty simple and common task.
var log = console.log;
log('\(◎o◎)/!');
It makes sense to me that this is soemthing worth supporting.
See other WHATWG repositories for examples.
Question: are strings like %6.9f
formatting specifiers?
As of commit 79390cb the answer seems to be no, but chrome and firefox both treat it as a specifier:
> console.log("|%6.9f|",1.23)
|1.23|
Add @bcowgill to the acknowledgments for his upstream report at jsdom/jsdom#1562
E.g. ToString should link to the ES spec, and Formatter() should link to the formatter AO.
This is probably a bug in emu-algify, so assigning to me.
The function console.debug()
is not present in some environments, e.g. Node.js, and according to whatwg, MSDN and Chrome documentation, it duplicates the functionality of console.log()
. Compare with the Node console documentation which makes no mention of debug()
.
Thus console.debug()
seems to serve no useful function. See also microsoft/TypeScript#11751.
Should console
be enumerable on the global object or not?
Current descriptor attributes in different environments: Object.getOwnPropertyDescriptor(globalObject, "console")
With the push in #3 to have console
be a namespace object like Math
and JSON
, then it makes sense to have similar descriptor attributes to those objects. In fact, all environments agree on the descriptor attributes for Math
and JSON
. This matches the Safari implementation.
Proposal:
I don't have a strong preference one way or the other.
Would there be an advantage to having console
be enumerable?
If rest is empty, perform Printer(logLevel, first). Abort these steps.
Printer()s second argument is a list, not an object. This should be Printer(logLevel, « first ») to denote the list.
When a console.assert
fails (e.g. console.assert(1 == 2)
) in some browsers it triggers Pause on Exception but in others it does not:
I don't have a computer with Windows so unfortunately I can't test Edge.
I find triggering Pause On Exception on console.assert
failures to be useful behavior so I believe Firefox should align with Safari and Chrome on this.
The don't repeat yourself (DRY) principle of software development says that:
console.assert(_ instanceof Promise)
if (!(_ instanceof Promise)) reject()
Is remiss compared to:
if (console.assert(_ instanceof Promise)) reject()
See https://lists.w3.org/Archives/Public/public-web-perf/2014Jun/0036.html and https://esdiscuss.org/topic/a-way-of-explicitly-reporting-exceptions for interest.
See https://www.w3.org/Bugs/Public/show_bug.cgi?id=26182 for the previous issue on this (merged into this new one since the idea seems to be to have it on console).
Node.js does not have access to what stdio (e.g. console) data goes to. Once it has gone through "the pipe" we are usually not able to alter it.
Currently Node.js has 4 possible output options for console (stdout/stderr) output:
Current specification for console.trace
seems either incomplete or at odds with the current "print a stack trace" behaviour in most console implementations.
What, if any, are the plans on standardisation of console.trace
?
Possibly related to whatwg/javascript#26
If the build fails, we shouldn't deploy. Oops.
console.log("%s", {toString:function() { return "foo"; }})
Chrome prints Object
whereas the spec seems to suggest foo
is the correct response
All the logging functions currently allow the use of formatting specifiers, with the exception of assert. To avoid confusion for web developers, the assert function should work with formatting specifiers.
console.assert(false, 'string: %s', 'test');
//-> Assertion failed: string: test
What should the behavior be if a console group is still open when a stack completes?
Should it continue grouping until a user ends with groupEnd, or should it close automatically?
What should be the behavior of console.assert
with no arguments?
Currently the spec shows a single required argument and optional data.
interface Console {
void assert(boolean condition, any... data);
};
Most implementations however allow for console.assert()
to work, and fire an assert:
I think there is a valid use case for no arguments. console.assert()
could used by developers as a "Assert Not Reached". It is slightly simpler then console.assert(false)
, slightly worse than console.assert(false, "Unhandled type %s", type)
, but effectively equivalent to both.
So it may be appropriate to make the condition itself optional.
Proposal:
interface Console {
void assert(optional boolean condition, any... data);
};
I think it is clear that implementations should fire an assert (in any way they wish) when there are no arguments. The implicit undefined
value for condition is falsey.
Presently, Chrome logs any >2xx resource request (at least those issued via XHR and fetch) to console as an error. I tried adding window.onerror= function(e){ debugger; e.preventDefault() }
to try to preempt & catch this behavior but the breakpoint never trips and there appears to be no way to prevent this error.
I'd opened whatwg/fetch#428 thinking perhaps fetch could/should deal with this by creating some new flag for fetch to indicate that it was ok if the request failed, and to not forcibly/always log to console. Spec authors there indicated it was not in fetch's hands.
I've just opened https://bugs.chromium.org/p/chromium/issues/detail?id=677599 with Chromium since it appears to be chiefly a Chrome behavior. Firefox does not log forcibly log errors. I don't own the OSes that Safari or Edge run on so I'm not sure if I have a way to test those browsers.
As per annevk's mention in fetch#428, I do think this is perhaps something Console might be cut out to deal with. This seems like a highly unspecified use of console, and console could perhaps designate some generals ways for developers to better control browser's undesignated behavior. I thought the onerror handler I specified in my first paragraph should have done something, for example, given that Chrome was marking what was happening as an error in my console.
Node.js has implemented a console.dir(obj[, options])
since Node v0.1.101.
From what I can tell, it appears to be a more direct sort of proxy to util.format()
allowing the passing of options rather than additional objects.
The current steps for Logger seemed confusing. I highlighted some parts:
perform Printer(logLevel, first)
instead?return Printer
and let Printer
return undefined. This will follow some consistency with other methods as Formatter(args)
.Perform Logger
, they could also be replaced by Return Logger
.Hi! I'm new here and just came from the tweet I saw mentioning this spec.
Working every day with unit tests projects, as QUnit, I wonder if we could improve the API for console.assert
.
I haven't elaborated anything yet, but I've got some immediate ideas that could be very useful for other tests and assertion libraries:
console.assert
calls/resultsThese changes can be very helpful for unit test tools and respective cross compatible reporters, e.g. https://github.com/js-reporters/js-reporters.
These seem to exist in a few different browsers.
Edge has a method console.countReset(label)
which allows resetting a counter. This seems useful, and in general it's better to add console methods than remove them, in my opinion.
If we spec this we should make sure that its behavior with no arguments, or undefined, is the same as that is decided for console.count()
. (For that, see #88.)
I think this is ready to become a WHATWG Standard, if you guys want. Are you interested? If so the first step would be to transfer it to the whatwg organization; then we can get you a subdomain and do a blog post announcement and so on.
The console.table
method is going to need an algorithm to help bridge developer input with that of Print
.
The method signature is:
void table(any tabularData, optional sequence<DOMString> properties);
If tabularData
is an array of objects, Chrome displays this as a nice table.
If properties
is included, the table is filtered to only disable those keys (Chrome allows a single key to be selected if property
is not an array).
If tabularData
is an array of arrays, properties
can be indexes.
Chrome does not seem to support other types of tabularData
. For example, a Set
is simply displayed as if it was passed to console.log
with no formatting specifiers.
If the first argument is a string, this is still not a simple aliasing of console.log
Anything that can be enumerated should probably be considered valid tabularData
, but that's gets us into problems with infinite generators.
@domenic As Print
's job is to "simply to print the List.", do we need to create a special PrintTable
function? Or do we have a Table
structure that can be passed in the List and that Print
knows how to print?
The spec for console.count()
with no arguments does not match implementation behavior and is not as useful as it could be.
Currently:
void count(optional DOMString label = "");
With the algorithm roughly being:
1. Increment an internal counter for the `label`
2. Log `label: <count>`
I feel it was originally the intention of console.count()
with no arguments is to create a unique counter. That way you can have multiple unique counters for their location in source code but use a label
if you want to increment a shared counter.
There was discussion on this a long time ago in multiple places to fix and improve existing implementations, which treated no arguments as (source:line) but should be (source:line:column) to be unique. My proposal at the time was:
I'd like to propose the following console.count changes:
(1) Share console.count(<title>) counters with the same title.
If you want to increment a "shared" counter in multiple places, that is
currently only possible if if you manage to put the counters on the
same line.
(2) Make each console.count() without a title completely independent.
If you really want to know exactly how many times a particular console.count has
been incremented it shouldn't matter what other console.count's appear on the same
line as that one.
It got some support.
Current implementation behavior for multiple console.count()
on the same line still sucks:
Current implementation behavior for console.count("label")
is roughly equivalent:
It is also worth noting that Edge has console.countReset(label)
. Which works very well when it is required that there is a label. Perhaps if we decide to spec this, then console.countReset()
with no arguments should probably clear all labels.
Proposal:
void count(optional DOMString label);
Algorithm:
1. If no label was provided, let `label` be a unique label for this callsite.
2. Increment an internal counter for the `label`
Note:
NOTE: An example implementation of creating a unique label for a
console.count callsite would be the (sourceId:line:column)
combination of where the console.count appears. No two
console.counts would share this combination. Whatever the unique
label is, it should not be possible for a user provided label to
increment this unique label. One way this could be achieved by
implementors is internally prefixing user provided labels and engine
generated labels differently, to guarantee no collisions.
You'll notice I dropped the spec's current suggestion to log <label>: <value>
. I think that is outdated. If you increment a counter 100 times, should the developer tools really be spammed with 100 counts? I think developer tools should be given the freedom to display counters without the log. I think there is a wealth of opportunity here and nobody is taking advantage of. A naive browser implementation may be to simplify log the count; a better user experience might be a view that shows all the counters, their values updating live, and the ability to reset and jump to their location.
My wording for the NOTE is not the best. Please help it ;)
The console.count
, console.timeEnd
and console.assert
methods do two things:
In many debugging scenarios, it would be very useful to get the computed value as a return value from the console.*
call. Enables things like logging difference between two timers or counts etc.
The console.assert
return value proposal is already reported as issue #63.
https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope
We invented it for stuff like this, basically.
https://console.spec.whatwg.org/commit-snapshots/36c3ee56b8471c82ec5ea88dcbaf223235b22a3e/#assert
If condition is false, perform Logger("error", data).
A call like console.assert(false)
would then call Logger("error", [])
, but the implementation of Logger
states as the first item:
- If
args
is empty, abort these steps.
I would expect the behavior to log something though - and the participants in the discussion around #56 seem to make the same assumption.
When calling console.assert(false)
in various browsers, something is logged in that case:
Assertion failed: console.assert
with level errorAssertion Failed
with level errorundefined
with level errorAssertionError: false == true
(false
is static, same result for console.assert(0)
)I'd propose to add a section that clarifies this:
Should we make a clear recommendation of what the String in (3) should look like? Or leave it open to implementers, e.g. just say "a string, indicating that some assertion failed (e.g. ...)"?
For reference, calling console.assert(false, "foo")
in various browsers:
Assertion failed: foo
with level errorAssertion Failed: foo
with level errorfoo
with level errorfoo
with level errorAssertionError: foo
EDIT: Didn't have access to Edge, added @domenic's findings.
There should be a way to print how much time has passed since a timer has started without removing the timer.
In Chrome calling timeEnd
currently doesn't remove the timer, so you can call timeEnd multiple times.
console.time("abc")
console.timeEnd("abc")
console.timeEnd("abc")
// abc: 0.006ms
// abc: 0.281ms
The timer is reset only when time
is called again with the same label. Firefox and Node remove the timer when timeEnd
is called, as the spec says.
To be able to see intermediate values the spec could either be changed to recommend Chrome's behavior, or a new timeLog
(or similar) function could be introduced, which prints the duration without affecting the timer itself.
console.time("abc")
console.timeLog("abc")
console.timeEnd("abc")
Right now we're defining the console
exposed to Window and WorkerGlobalScope as a type of Console
. In today's browsers, you'll be able to assign anything you want to the console
variable.
This issue should determine if we want or should disallow this, and what changes need to be made to the IDL and supporting text.
What should be the behavior of console.time
with no arguments?
Currently the spec shows a single non-optional argument:
interface Console {
void time(DOMString label);
void timeEnd(DOMString label);
};
Current behavior of console.time()
and console.timeEnd()
:
"default"
, console.warns when called and the timer is/not runningCurrent behavior of console.time("name")
and console.timeEnd("name")
:
I have to admit I rather like both node and Edge's behavior here. WebKit's is nice in that it indicates a likely user error that would otherwise cause a developer to scratch their head, but an exception is overkill. node and Edge make it simple to do a quick and dirty time & timeEnd, which is what developers will want most of the time.
I would suggest a move in the Edge direction.
Proposed:
interface Console {
void time(optional DOMString label = "default");
void timeEnd(optional DOMString label = "default");
};
Playing around with Edge's implementation, it seems that any falsey value (e.g. false
, 0
, NaN
, ""
, ...) is coerced to the string "default"
. I don't know of an IDL attribute for this kind of behavior ([TreatFalseyAs="default"]
), or if it would be desirable to spec this quirk. However, it does seem very user friendly.
Comparing node and Edge, node is rather ambiguous. node seems to treat label
as a value and ambiguously displays string names for values that aren't treated as strings internally. For instance console.time(123)
and console.time('123')
are treated uniquely, but based on warning messages from node they are not distinguishable. Likewise undefined
versus "undefined"
. I could see this being extended to with object / Symbol values.
Ultimately I don't think non-string values as identifiers are necessary for console.time()
. And given all browsers currently expect strings, it seems easier to stick with that expectation.
Update: Added node.js to the discussion.
Add language that ensures that console
is always visible and usable to scripts, even if the developer console has not been opened or does not exist.
Hi,
I would like to request for a couple features, on request we should have a method that can output everything console has recorded so far like a stack list.
This is useful when you need to save it programmatically rather than debugging manually.
I would also like an event listener, so we can assign a handler and do something when there is a new entry on log, warn, error etc. Again for the same reason.
For the any...
methods, I assume they are probably valid. But for the ones that include type conversions, we need to check. For example:
console.time({ toString() { throw new Error("boo"); } })
does not throw; in Chrome, it does. Chrome at least seems to follow time(DOMString label)
.console.count({ toString() { throw new Error("boo"); } })
does not throw in Chrome. So count(optional DOMString label = "")
doesn't seem quite right.console.table({}, (function*() { yield "a"; throw new Error("b"); }()))
doesn't seem to throw. So table(any tabularData, optional sequence<DOMString> properties)
doesn't seem right. This is related to #21.Often specifications want to give hints at things that can be reported to a developer console, if there is any. Should we formalize that in the Console Standard?
(I was looking at fixing whatwg/fetch#259 and then I wondered whether we should have some shared mechanism across specifications.)
console.takeHeapSnapshot
is available in some browsers, so it should be standardized.
Edge had it originally and describe it in their documentation here and over here for debugging JavaScript Memory in the browser and apps. When Safari/WebKit added Memory Debugging they adopted the same name and semantics. It was described briefly in a webkit.org blog post.
Proposal:
interface Console {
void takeHeapSnapshot(optional DOMString label);
};
Using console.takeHeapSnapshot
without a label is fine. User agents can just give their own label such as Snapshot 1
, Snapshot 2
, etc. When providing a label developer tools can decide to show that label in their user interface if they wish. Labels can give useful context information for users using the API. For example Snapshot 1 – Before Operation
, Snapshot 2 – After Operation
.
Right now the section https://console.spec.whatwg.org/#formatting-specifiers is kind of disconnected from the main text. https://console.spec.whatwg.org/#formatter handles some of them, but the ones that require complex UI are ignored by the rest of the spec's algorithms.
I am not sure how best to reconcile this. Maybe Formatter() should reference the tables in #formatting-specifiers, and remove the algorithm steps? Maybe Formatter() should get an additional line for each of %o, %O, or %c? But these don't act like type conversions, exactly...
In any case one goal should be to ensure there is only one normative source of truth---either the algorithm or the tables. If we decide on the algorithm being normative, then we can keep the tables, we just need to mark them non-normative.
In Node.js, a %j
formatting specifier runs JSON.stringify()
on the related arg. I am unsure what checks it makes other than '[Circular]'
, but I can take a look.
Example:
$ node
> console.log('JSON: %j', { greeting: 'hello!' })
JSON: {"greeting":"hello!"}
More information can be found in our docs on util.format(format[, ...args])
(Effectively our equivalent of the spec's Format function.)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.