How to create hyperlinks linked to javascript functions in Chrome's console.log?
The Google Chrome console, like many other browser's developer tools consoles, automatically parses any URL into a link to that exact page. This is the only way of obtaining such URLs, and, unfortunately, you cannot actually log "custom URLs".
This means that the following logs will be turned into a clickable link automatically:
console.log('http://example.com');
console.log('www.example.com');
console.log('ftp://mysite.com');
console.log('chrome://history')
console.log('chrome-extension://abcdefg...');
but, on the contrary, the following ones won't:
console.log('example.com');
console.log('<a href="http://www.example.com">Link</a>');
console.log('javascript:doSomething(someValue);');
It's been four years since OP asked this, but they can accomplish their stated goal as follows:
Create a getter that has a side-effect. (The side effect can be to directly animate your thing.)
class YourThing {
get __doAnythingYouWant() {
// ...like console.log('my thing:', this);
}
}
Alternatively:
var yourObject = {
get __doAnythingYouWant() {
// ...like an animation in DOM... this.myDomElement.style...
}
};
How to use it:
console.log(yourObject);
> {
get __doAnythingYouWant: (...) <-- click here!
}
> "you clicked the dots!"
The downside is you can only invoke the getter once. You could maybe get around this by deleting it and redefining it from within itself, with every invocation. You could make that less hackish by creating some kind of getter-defining function with Object.defineProperties, and some wrapper that takes a regular function and returns a function that does what it normally does, then redefines the getter. Clicking on it once was good enough for me, but if you wanted to you'd do it like this:
function addDebuggerButton(obj, f) {
var buttonName = `__${f.name}`;
Object.defineProperty(obj, buttonName, {
get: function() {
f.apply(this, arguments);
delete this[buttonName];
addDebuggerButton(obj, f);
},
configurable: true
});
return obj;
}
It's important to set the configurable
property, which just lets you redefine it after defining it.
It works:
addDebuggerButton({a:1,b:2}, function myButton() {
this.c = Math.random();
console.log('you pressed the button!', this);
});
> {a: 1, b: 2}
a: 1
b: 2
__myButton: (...) <-- click here!
get __myButton: ƒ ()
__proto__: Object
> you pressed the button! {a: 1, b: 2, c: 0.27574428165568676}
a: 1
b: 2
c: 0.27574428165568676
__myButton: (...) <-- click here again
get __myButton: ƒ ()
__proto__: Object
> you pressed the button! {a: 1, b: 2, c: 0.43171172657344337}
You can modify this as appropriate to work with classes. You could even add a hidden state to this by adding a default parameter to the addDebuggerButton function (so your button could say "you pressed the button 3 times!").
The other horribly hackish way to do this is to write a url like http://127.0.0.1:9999/myLocalWebserver/horribleWorkaround?{"metadata":"etc"}
. The URL would be interpreted by your local webserver you're testing your app out of, and would initiate some kind of push mechanism (or queue onto a poll mechanism), that would propagate to the webpage live.
... Of course, it would probably be more elegant to compile Chromium yourself with a custom patch...
The third way, since chrome-extension:// urls are allowed, is perhaps to write an extension that converts certain clicks into javascript. There may perhaps be security implications (to be safe, you would not let this run except on whitelisted pages, but even then there are security implications I have not thought of since I'm not entirely familiar with that area).