This is the story of how I wanted to restore the console.log on the sites that prevent you to use it by overriding the object on the page load. I’ll tell my experience and meanwhile, I’ll show you how to create your own google chrome extensions.
Some applications tend to disable/remove the console.log, usually to hide the debugging messages and/or avoid problems with older versions of IE. For instance, Magento has a script code that erases all the window.console code. This can be very annoying when you have to debug some javascript code, as you cannot print anything on the console. Your options are reduced to either use the built-in Javascript debugger, by putting a break point on the code, or go back to the old times of the well-known alerts. Both options are not so bad, but I am a bit stubborn, and I want to be able to use my loved console.log anywhere and at any time, so I had to fix this. Please, note that I just could remove the offending code from the magento javascript file, but that would be too easy and uninteresting at all, not to mention that I rather leave it disabled at least for the production environment, and I didn’t want to make a environment-dependent code.
I thought that maybe I would be able to install some browser extension that would do all the job for me just by pressing one button, but after a depth research I was unable to find it. It seemed like nobody had the same problem, or nobody cares about it.
I was wondering how to make my own workaround. My idea was to save a copy of the window.console object into a variable just before the evil code was executed. Then, I just would need to restore the saved copy in window.console, and hopefully I would get the console working.
I remembered that I’ve used once a Firefox extension called Greasemonkey that allows to inject Javascript code on the pages, so I gave it a try. Unluckily, after some failed attempts I realized that all the scripts are executed after the page loaded event, wich didn’t serve for my purposes.
After googling for a while, I come up to the conclusion that the only way to do what to do that was to create my own browser extension. I had never tried something like that before, so I decided to try it. After having a look at Chrome documentation, I started developing my first version. It’s ridiculously easy to create a Google Chrome Extension, you just need a manifest.json (specifying a few settings), and a javascript file (depending on your needs, of course, you might need more stuff).
This is how my manifest.json looks:
{ "name": "Enable Console.log - The Developers World Is Yours", "description": "This extensions automatically restores the console object, if any javascript code attempts to remove it.", "manifest_version": 2, "version": "1.0", "content_scripts": [ { "matches": ["http://*/*"], "js": ["enable.js"], "run_at": "document_start" } ] }
Basically, the first lines are just standard fields, and the interesting part is focused on the last three lines:
“matches”: [“http://*/*”]: Means that my extension should be executed at any page.
“js”: [“enable.js”]: This is the source file of the Javascript code that will be executed.
“run_at”: “document_start”: This line specifies WHEN should the script be executed. In my case, I want it to be executed at the very begining, so I’ve set the option “document_start”.
More information regarding the options of this settings can be found at google documentation page.
With the manifest.json done, I could focus on the interesting part, my own extension. I started doing some tests and the expectations were good. I was able to print debug messages in the console from my extension, which means that it was being executed before the page javascript code. This should be enough for me to save in memory a copy of the window.console object and then I just have to wait some time and restore it, if needed.
This is the code I had so far on my “enable.js” file:
var __working_console = window.console; //Each second, try to put a console.log message var count = 5; var test = setInterval(function(){ console.log("Console is still working!"); //Stop it after a while if (count == 0) { window.console = __working_console; //Try to restart the console, just in case (IT DOESN'T WORK) clearInterval(test); } else { count = count -1; } }, 1000);
I was on my way doing the script, when I realized that I have a big problem: My script was being executed on a different context. It seems that from a Chrome Extension script, you are able to retrieve data from the page, but your code isn’t actually being executed likely a common script loaded on he header’s page (or anywhere else). This means that, even though I was able to save a copy of a working version of window.console object, I was unable to restore it in the page context. Because the window object where the Chrome extension is executed, is different from the window object of the page, so no matters what I do, that I won’t be able to change anything.
Very bad news, but did not give up, and I did well, because although I didn’t know yet, I was very close to find the solution. Do you want to know how I did it, eventually? Do not miss the second part!
Pingback: Creating Google Chrome Extensions - II • The Developer World Is Yours