WebKit/Safari supports the console object, which is similar to what Firebug does. But what exactly is supported? There is a console documentation for Firebug, but where can I find the console documentation for Safari/WebKit?
Supported methods were originally:
console.log()
console.error()
console.warn()
console.info()
Newer versions of WebKit also add the following methods making the WebKit console API almost identical to Firebug's console API:
console.count()
console.debug()
console.profileEnd()
console.trace()
console.dir()
console.dirxml()
console.assert()
console.time()
console.profile()
console.timeEnd()
console.group()
console.groupEnd()
(New information based on the WebKit nightly build WebKit-SVN-r37126, at the time of writing these methods aren't available in Safari)
The console API is documented by Apple in the Console section of the Safari Developer Guide.
I know this is an old and answered question, but you can also just open the console and type console.__proto__, and you'll get an expandable list of everything it supports.
Firebug's Console API documentation has moved here:
http://getfirebug.com/wiki/index.php/Console_API
Try this out:
console.dir(console)
The Console object appearantly has a built-in 'API', in the form of a 'private property' you can reveal by doing this in the Webkit javascript-console
> for(o in console) console.dir(o)
_commandLineAPI
log
warn
…
_commandLineAPI:
> console.dir(_commandLineAPI)
CommandLineAPI
$0: "—"
$1: "—"
$2: "—"
$3: "—"
$4: "—"
$$: bound: function () {
$x: bound: function (xpath, context) {
clear: bound: function () {
copy: bound: function (object) {
dir: bound: function () {
dirxml: bound: function () {
inspect: bound: function (object) {
keys: bound: function (object) {
monitorEvents: bound: function (object, types) {
profile: bound: function () {
profileEnd: bound: function () {
unmonitorEvents: bound: function (object, types) {
values: bound: function (object) {
__proto__: CommandLineAPI
At the moment safari console URL is broken.
Here's copy(press "Run code snippet"):
<article id="contents" tabindex="0" role="main" class="isShowingTOC">
<a id="top" name="top"></a>
<a id="INDEX" href="/web/20170322101551/https://developer.apple.com/library/content/documentation/AppleApplications/Conceptual/Safari_Developer_Guide/index.html" style="display:none;" onclick="s_objectID="http://web.archive.org/web/20170322101551/https://developer.apple.com/library/content/documentati_9";return this.s_oc?this.s_oc(e):true"></a>
<a name="//apple_ref/doc/uid/TP40007874-CH6-SW1" title="The Console"></a><h1 id="pageTitle">The Console</h1><p>The console offers a way to inspect and debug your webpages. Think of it as the Terminal of your web content. The console has access to the DOM and JavaScript of the open page. Use the console as a tool to modify your web content via interactive commands and as a teaching aid to expand your knowledge of JavaScript. Because an object’s methods and properties autocomplete as you type, you can see all available functions that are valid in Safari.</p><p>For example, open the console and type <code>$$(‘p’)[1]</code>. (<code>$$</code> is shorthand for <code>document.querySelectorAll</code>—see more shorthand commands in <span class="content_text">Table 5-1</span>.) Because this paragraph is the second instance of the <code>p</code> element on this page (<code>[1]</code> in a 0-based index), the node represents this paragraph. As you hover over the node, its position on the page is visibly highlighted. You can expand the node to see its contents, and even press Command-C to copy it to your clipboard.</p><section><a name="//apple_ref/doc/uid/TP40007874-CH6-SW5" title="Command-Line API"></a><h2 class="jump">Command-Line API</h2><p>You can inspect HTML nodes and JavaScript objects in more detail by using the console commands listed in <span class="content_text">Table 5-1</span>. Type the command-line APIs interactively within the console.</p><p>If your scripts share the same function name as a Command-Line API function, the function in your scripts takes precedence.</p><a name="//apple_ref/doc/uid/TP40007874-CH6-SW7" title="Table 5-1Commands available in the Web Inspector console"></a><div class="tableholder"><table class="graybox" border="0" cellspacing="0" cellpadding="5"><caption class="tablecaption"><strong class="caption_number">Table 5-1</strong> Commands available in the Web Inspector console</caption><tbody><tr><th scope="col" class="TableHeading_TableRow_TableCell"><p>Command</p></th><th scope="col" class="TableHeading_TableRow_TableCell"><p>Description</p></th></tr><tr><td scope="row"><p><code>$(</code><em>selector</em><code>)</code></p></td><td><p>Shorthand for <code>document.querySelector</code>.</p></td></tr><tr><td scope="row"><p><code>$$(</code><em>selector</em><code>)</code></p></td><td><p>Shorthand for <code>document.querySelectorAll</code>.</p></td></tr><tr><td scope="row"><p><code>$x(</code><em>xpath</em><code>)</code></p></td><td><p>Returns an array of elements that match the given <span class="content_text">XPath</span> expression.</p></td></tr><tr><td scope="row"><p><code>$0</code></p></td><td><p>Represents the currently selected node in the content browser.</p></td></tr><tr><td scope="row"><p><code>$</code><em>1..4</em></p></td><td><p>Represents the last, second to last, third to last, and fourth to last selected node in the content browser, respectively. </p></td></tr><tr><td scope="row"><p><code>$_</code></p></td><td><p>Returns the value of the last evaluated expression.</p></td></tr><tr><td scope="row"><p><code>dir(</code><em>object</em><code>)</code></p></td><td><p>Prints all the properties of the object.</p></td></tr><tr><td scope="row"><p><code>dirxml(</code><em>object</em><code>)</code></p></td><td><p>Prints all the properties of the object. If the object is a node, prints the node and all child nodes.</p></td></tr><tr><td scope="row"><p><code>keys(</code><em>object</em><code>)</code></p></td><td><p>Prints an array of the names of the object’s own properties.</p></td></tr><tr><td scope="row"><p><code>values(</code><em>object</em><code>)</code></p></td><td><p>Prints an array of the values of the object’s own properties.</p></td></tr><tr><td scope="row"><p><code>profile(</code><em>[title]</em><code>)</code></p></td><td><p>Starts the JavaScript profiler. The optional argument <code>title</code> contains the string to be printed in the header of the profile report. See <span class="content_text">JavaScript and Events Recording</span>.</p></td></tr><tr><td scope="row"><p><code>profileEnd()</code></p></td><td><p>Stops the JavaScript profiler and prints its report. See <span class="content_text">JavaScript and Events Recording</span>.</p></td></tr><tr><td scope="row"><p><code>getEventListeners(</code><em>object</em><code>)</code></p></td><td><p>Prints an object containing the object’s attached event listeners.</p></td></tr><tr><td scope="row"><p><code>monitorEvents(</code><em>object[, types]</em><code>)</code></p></td><td><p>Starts logging all events dispatched to the given object. The optional argument <code>types</code> defines specific events or event types to log, such as “click”.</p></td></tr><tr><td scope="row"><p><code>unmonitorEvents(</code><em>object[, types]</em><code>)</code></p></td><td><p>Stops logging for all events dispatched to the given object. The optional argument <code>types</code> defines specific events or event types to stop logging, such as “click”.</p></td></tr><tr><td scope="row"><p><code>inspect(</code><em>object</em><code>)</code></p></td><td><p>Inspects the given object; this is the same as clicking the Inspect button.</p></td></tr><tr><td scope="row"><p><code>copy(</code><em>object</em><code>)</code></p></td><td><p>Copies the given object to the clipboard.</p></td></tr><tr><td scope="row"><p><code>clear()</code></p></td><td><p>Clears the console.</p></td></tr></tbody></table></div><p>The functions listed in <span class="content_text">Table 5-1</span> are regular JavaScript functions that are part of the Web Inspector environment. That means you can use them as you would any JavaScript function. For example, you can assign a chain of Console API commands to a variable to create a useful shorthand. <span class="content_text">Listing 5-1</span> shows how you can quickly see all event types attached to the selected node.</p><a name="//apple_ref/doc/uid/TP40007874-CH6-SW6" title="Listing 5-1Find the events attached to this element"></a><p class="codesample clear"><strong class="caption_number">Listing 5-1</strong> Find the events attached to this element</p><div class="codesample clear"><table><tbody><tr><td scope="row"><pre>var evs = function () {<span></span></pre></td></tr><tr><td scope="row"><pre> return keys(getEventListeners($0));<span></span></pre></td></tr><tr><td scope="row"><pre>};<span></span></pre></td></tr></tbody></table></div><p>After defining this function, inspect the magnifying glass in the top-right corner of this webpage, and type <code>evs()</code> in the console. An array containing the string “click” is returned, because there is a click event listener attached to that element.</p><p>Of course, these functions shouldn’t be included in your website’s JavaScript files because they are not available in the browser environment. Only use these functions in the Web Inspector console. Console functions you can include in your scripts are described in <span class="content_text">Console API</span>.</p></section><section><a name="//apple_ref/doc/uid/TP40007874-CH6-SW3" title="Console API"></a><h2 class="jump">Console API</h2><p>You can output messages to the console, add markers to the timeline, and control the debugger directly from your scripts by using the commands listed in <span class="content_text">Table 5-2</span>.</p><div class="importantbox clear"><aside><a name="//apple_ref/doc/uid/TP40007874-CH6-DontLinkElementID_5" title="Important"></a><p><strong>Important:</strong> These functions exist to aid development and should not be included in any of your production JavaScript.</p><p></p></aside></div><a name="//apple_ref/doc/uid/TP40007874-CH6-SW8" title="Table 5-2JavaScript functions available in the Console API"></a><div class="tableholder"><table class="graybox" border="0" cellspacing="0" cellpadding="5"><caption class="tablecaption"><strong class="caption_number">Table 5-2</strong> JavaScript functions available in the Console API</caption><tbody><tr><th scope="col" class="TableHeading_TableRow_TableCell"><p>Function</p></th><th scope="col" class="TableHeading_TableRow_TableCell"><p>Description</p></th></tr><tr><td scope="row"><p><code>console.assert(expression, object)</code></p></td><td><p>Asserts whether the given expression is true. If the assertion fails, prints the error and increments the number of errors in the activity viewer. If the assertion succeeds, prints nothing.</p></td></tr><tr><td scope="row"><p><code>console.clear()</code></p></td><td><p>Clears the console.</p></td></tr><tr><td scope="row"><p><code>console.count([title])</code></p></td><td><p>Prints the number of times this line has been called.</p></td></tr><tr><td scope="row"><p><code>console.debug(object)</code></p></td><td><p>Alias of <code>console.log()</code>.</p></td></tr><tr><td scope="row"><p><code>console.dir(object)</code></p></td><td><p>Prints the properties and values of the object.</p></td></tr><tr><td scope="row"><p><code>console.dirxml(node)</code></p></td><td><p>Prints the DOM tree of an HTML or XML node.</p></td></tr><tr><td scope="row"><p><code>console.error(object)</code></p></td><td><p>Prints a message to the console with the error icon. Increments the number of errors shown in the activity viewer.</p></td></tr><tr><td scope="row"><p><code>console.group([title])</code></p></td><td><p>Prints subsequent logs under a disclosure of the given title.</p></td></tr><tr><td scope="row"><p><code>console.groupEnd()</code></p></td><td><p>Ends the previously declared console grouping.</p></td></tr><tr><td scope="row"><p><code>console.info(object)</code></p></td><td><p>Alias of <code>console.log()</code>.</p></td></tr><tr><td scope="row"><p><code>console.log(object)</code></p></td><td><p>Prints the object to the console with the log icon. Increments the number of logs shown in the activity viewer.</p></td></tr><tr><td scope="row"><p><code>console.markTimeline(</code><em>label</em><code>)</code></p></td><td><p>Marks the Timeline with a green vertical dashed line that indicates when this line of code was called. See <span class="content_text">Recording Timelines</span>.</p></td></tr><tr><td scope="row"><p><code>console.profile(</code><em>[title]</em><code>)</code></p></td><td><p>Starts the JavaScript profiler. The optional argument <code>title</code> contains the string to be printed in the header of the profile report. See <span class="content_text">JavaScript and Events Recording</span>.</p></td></tr><tr><td scope="row"><p><code>console.profileEnd(</code><em>[title]</em><code>)</code></p></td><td><p>Stops the JavaScript profiler and prints its report. See <span class="content_text">JavaScript and Events Recording</span>.</p></td></tr><tr><td scope="row"><p><code>console.time(</code><em>name</em><code>)</code></p></td><td><p>Starts a timer associated with the given name. Useful for timing the duration of segments of code.</p></td></tr><tr><td scope="row"><p><code>console.timeEnd(</code><em>name</em><code>)</code></p></td><td><p>Stops the timer associated with the given name and prints the elapsed time to the console.</p></td></tr><tr><td scope="row"><p><code>console.trace()</code></p></td><td><p>Prints a stack trace at the moment the function is called. See <span class="content_text">Figure 4-2</span>.</p></td></tr><tr><td scope="row"><p><code>console.warn(</code><em>object</em><code>)</code></p></td><td><p>Prints a message to the console with the warning icon. Increments the number of warnings shown in the activity viewer.</p></td></tr><tr><td scope="row"><p><code>debugger</code></p></td><td><p>Stops JavaScript execution at the current line. This is the equivalent of setting a breakpoint programmatically. See <span class="content_text">Breakpoints</span>.</p></td></tr></tbody></table></div></section>
<div class="copyright"><br><hr><div align="center"><p class="content_text" lang="en" dir="ltr"> Updated: 2016-09-13</p></div></div>
<div id="pediaWindow">
<div id="pediaHeader"></div>
<div id="pediaBody"></div>
</div>
</article>
Related
I need to run certain command "Run all" from Google Colab menu "Runtime" programmatically. It does not have any obvious "onclick" eventHandler which I could call from javascript code on that page.
Other "divs" on the page are OK to be called from js, for exapmle, I can connect to runtime using js code:
document.querySelector('#top-toolbar > colab-connect-button').shadowRoot.querySelector('#connect').click();
Runtime menu is a dropdown menu and I tried to .click() every <div> item inside it but no effect.
Also "Run all" command has a hotkey Ctrl + F9 but dispatching event to the document element has no effect. But I can send Enter command to any input field inside the notebook with this code:
document.querySelector('input.raw_input').dispatchEvent(new KeyboardEvent('keydown', {key: 'Enter'}))
Using Chrome code inspector Ctrl + Shift + I I looked inside "Run all" command and it looks like:
<div command="runall" class="goog-menuitem" role="menuitem" id=":1w" style="user-select: none;"><div class="goog-menuitem-content" style="user-select: none;">Run all<span class="goog-menuitem-accel">Ctrl+F9</span></div></div>
So I searched inside Sources tab of inspector code on the page and found occurrences of "runall" in https://colab.research.google.com/v2/external/external_polymer_binary.js file:
, Eja = X(new W({
id: "runall",
description: "Run all cells in notebook",
shortcut: IG(120)
120 - is a keycode of F9 button by the way. Also I found I think exact place where needed menu item is called:
case "runall":
d.runAll();
break;
but it's almost impossible for me to understand what is d. and where its reference!
Also I found many other interesting and useful commands like this.notebook.getKernel().isRunning() or c.notebook.getKernel().restart() but the question is the same all the time: what is the root object for those commands? I tried document. and window. but the result is "undefined" or "is not a function". I think that I could call runall() command in a string like:
document.**SOMETHING I DONT KNOW**.runAll()
I am very bad with frontend/js and its very difficult to find something in obfuscated code but if we have such function as .runAll() in javascript code which is connected to required menu item I thick it is possible to run it programmatically from console or javascript injection
Or maybe it is possible to dispatch a keyboard event Ctrl + F9 to some element in order to run this command thus the question is WHAT is the required object to dispatch the keyboard event
I spent a while combing through that javascript file for a similar reason, and finally figured out how to make this work.
Here's a function to programmatically run all cells:
function runAll() {
const F9Event = {key: "F9", code: "F9", metaKey: true, keyCode: 120};
document.dispatchEvent(new KeyboardEvent("keydown", F9Event));
}
Note that KeyboardEvent.keyCode is deprecated in favor of KeyboardEvent.code, but you still need to provide it here (as of 5/18/21) since it's the property Colab uses to check keyboard inputs.
You can also use metaKey: true and ctrlKey: true interchangeably, regardless of platform, since Colab just checks whether either KeyboardEvent.metaKey or KeyboardEvent.ctrlKey is present for shortcuts that require them.
Also I found many other interesting and useful commands like this.notebook.getKernel().isRunning() or c.notebook.getKernel().restart() but the question is the same all the time: what is the root object for those commands?
There's a global colab object that provides access to some (but not all) functionality. Most things are accessible through colab.global, e.g. to restart the kernel, you can use:
colab.global.notebook.kernel.restart()
Can I set a breakpoint on a standard JavaScript function? For example, can I pause the debugger every time context.beginPath() is called? Or every time that String.replace() is called?
UPDATE: What I meant by standard JavaScript function is functions built-in into the JavaScript engines.
Yes you can do this by overriding the original functionality by performing the following two steps:
Make a copy(reference really) of the original function:
mylog = console.log;
Override the original with your copy inserting the debugger statement:
console.log = function(){
debugger;
mylog.apply(this, arguments);
}
Now when called console.log will perform a breakpoint. (Note you'll have to handle different function arguments differently depending on the function be overriden)
Here is another example using an instance methods, for example String.prototype.replace:
let originalFunction = String.prototype.replace;
String.prototype.replace = function(...args) {
debugger;
return originalFunction.call(this, ...args);
}
console.log('foo bar baz'.replace('bar', 'BAR'));
Are you looking for the debugger statement?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger
There are 3 ways to set up a breakpoint and debug the code.
1. Chrome dev-tools / Firebug:
Using Chrome developer tools or firebug to locate the line of
JavaScript, then set the breakpoint with the mouse. In chrome, you
should first open(ctrl+shirt+I) to open developer tools.
Select the script tab or click on (ctrl+P) to open then desired file.
Search the line on which you wanted to set a breakpoint and set a
breakpoint.
Whenever you execute your code next time in a browser, the breakpoint
is fired. In watch section, you may see every expression, all
variables in scope, and the call stack too.
2. Debugger
Using debugger statement, it fires every time and it helps when it
hard to find the execution of code.
debugger;
3. Webstorm IDE / Visual Studio Code
Webstorm IDE/Visual Studio Code have the facility to debug a code from
IDE.
Javascript is a really flexible language and probably following the way to override existing javascript and debug method then please use following a way of debugging.
var fnSetAttribute = Element.prototype.setAttribute;
Element.prototype.setAttribute = function(name, value) {
if (name == 'clone') {
debugger; /* break if script sets the 'clone' attribute */
}
fnSetAttribute.call(this,name,value); /* call original function to
ensure those other attributes are set correctly */
};
For more reference please review https://alistapart.com/article/advanced-debugging-with-javascript
Works in Google Chrome Console:
debug(console.log) // sets a breakpoint on "console.log" builtin
console.log("Hello")
It shows the Sources pane and says
🛈 Paused on debugged function
I have reviewed how to create custom errors in JS, and wrote following code:
function AssertException(message)
{
"use strict";
Error.captureStackTrace(this, AssertException);
Object.assign(this, {name: 'AssertException', message: message});
}
AssertException.prototype = Object.create(Error.prototype);
AssertException.prototype.name = 'AssertException'
Now, when I try to create instance and output it in console (in Chrome), it just shows it as object instead of error syntax (with stack in ellipsis block).
See screenshot for details.
Is there way to define an error class that its output will be shown as for standard error classes (with stack in ellipsis)?
PS. console.log(new AssertException('abc').stack) shows expanded stack as string.
Google Chrome Version 50.0.2661.94 m
Console output screenshot for details
Although I do not have any code to prove the point, I believe the difference is to due to different "handlers" used by Chrome.
The "Error" object and all its six subtypes are native objects. Therefore, for printing on console, Chrome uses a native handler. Perhaps, someone with more visibility to the chrome v8 source code can point to the exact handler.
The "AssertException" object created by your code is non-native. Hence, the use of "Object Handler" to print its contents.
FYI..you can check if a function is native or not using the following:
https://gist.github.com/hilbix/a298f4c969593fabb08074628dc304b8
I found a way to inject information into the Firefox Web Console, catching and modifying the return value of createMessageNode, modifying the web-console output:
Oddly enough, the elements returned don't seem to have any possible way to link them back to the object they represent - yet when you click [object Array], it always pops up to the right. How is this connected?
As a side note, when I click upward on the breadcrumbs to see where it came from on the stack trace, some items aren't shown in the debugger. Is this a bug, or are some JS modules compiled so as to never show their contents here? Is this the correct place to add in an array to the console line instead of always saying [object Array] etc.?
Update You can see and run this code above in this branch: https://github.com/programmin1/DevTools-Tweaks/tree/webconsoleOutputBetter
by inject info do you mean Services.console.logStringMessage and stuff?
https://developer.mozilla.org/en-US/docs/Console_service
If you want to access the chrome of the web console do this:
var devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
var HUDService = devtools.require("devtools/webconsole/hudservice");
var hud = HUDService.getBrowserConsole();
var btnClear = hud.chromeWindow.document.querySelector('.webconsole-clear-console-button');
btnClear.addEventListener('mouseover', function() {
hud.jsterm.clearOutput(true);
}, false);
var fieldFilter = hud.chromeWindow.document.querySelector('.hud-filter-box');
fieldFilter.value = 'rawr'
this code access the crhome window, you can access all the text dumped there. this example above modies the filter value, and also makes the clear button clear the web console on mouseoever, just an example of how to access web console if thats what you're doing
I'm trying to deconstruct part of Gmail and can't seem to be able to find what is happening (what functions are called) when a specific button is clicked.
I used Google Chrome's inspector and found the HTML for the button:
<tbody id=":8y" class="vC " idlink="" role="option" aria-labelledby=":8x :8w"><tr class="vI"><td><img class="vt SFzvCe IRnhDe BUw1sf" id=":8x" src="images/cleardot.gif" alt="Call phone"></td><td id=":8v" class="vr" colspan="2"><span id=":8w" class="HHshnc ">Call phone</span></td></tr></tbody>
In the "Event Listeners" section of the inspector under "click" I got this information:
isAttribute: false
lineNumber: 213
listenerBody: function B(H){return g.call(B.src,B.key,H)}
node: tbody#:8y
sourceName: https://mail.google.com/mail/u/0/?ui=2&view=js&name=main,tlist&ver=q0qiADndhKA.en.&am=!k3sV9...
type: click
useCapture: true
but that doesn't help me understand what's being called onClick.
What I'm trying to do is create a Greasemonkey script that will add this button to Gmail when it doesn't exist on a page.
TIA!
function B(H){return g.call(B.src,B.key,H)}
is clearly only a wrapper function that calls g. Function.call
[c]alls a function with a given this value and arguments provided individually.
As you can read on the linked MDC page, the first argument is the this object inside g, in this case B.src. The second and third parameter are passed as parameters to g.
So, you'll have to look for a function named g. The toString method might be helpful.
That said, given the goal you're trying to reach (“create a Greasemonkey script that will add this button to Gmail when it doesn't exist on a page”), I think it's not worth your time. If the button doesn't exist, I suspect it doesn't exist for a reason (e.g., g not being available on that page, or some other back-end function).