mobileConsole – JavaScript console for mobile devices.

When developing in JavaScript, I always get a little annoyed about the lack of a debug console on iOS. And when I say ‘lack’ I mean the complete ass backwards obfuscation introduced in iOS 6, requiring you to physically hook your iPhone to your (Mac only!) development computer to view debug output. This approach, including various remote debuggers that are out there, is much too tedious when you simply need to view a value, see the contents of an object or – more likely – see the error message(s) your script caused, indicating why it isn’t working in the first place.

To that goal, I have developed mobileConsole; a JavaScript console for mobile devices. It ‘extends’ the window.console to a visual, HTML-based console that shows you a console similar in appearance to Chrome’s excellent web inspector console. The main goal was to keep mobileConsole unobtrusive: not requiring any additional code. This is why I extended window.console so I could keep using all my regular console events, without having to add extra error reporting in my projects. This has resulted in mobileConsole being a ‘click-on’ script; it will just intercept all console (and window.onerror) events and display them, without modifying anything*.

*Just one small caveat: While mobileConsole is active, the reporting of source file and line numbers in the regular console is not always correct, as mobileConsole is ‘hijacking’ them, so lines appear to come from the mobileConsole script file. This is not really a downside, as mobileConsole is aimed at devices that do not have a console to begin with.

Demo

On a mobile device, mobileConsole should have already opened automatically. Otherwise, open it by clicking the green button. The buttons each trigger some regular, native console commands, as described. The ‘Trigger an error’ button triggers a non-existing function, which will result in an window.onerror ‘undefined’ error, which is handled by mobileConsole as well.

On a desktop, you can also open your Web Inspector’s console to see what is happening over there. Hint: while your ‘real’ console is open, trigger some console events (log, info, warn, error, trace) yourself to see mobileConsole handling them. Or, additionally, trigger some events from mobileConsole’s own console commandline (introduced in mobileConsole 0.5).

Note: not all devices support every one of these methods natively, in which case mobileConsole will emulate them, and log a ‘this method is not supported on this device’s original console’ message.

Features

Snap-in / click-on / fire and forget: just add it to your project, and it should work out of the box, completely unobtrusive (unless, of course, you’re using the global variable mobileConsole for some reason) and requiring no additional code. It will just catch your existing console-calls.

Small: 58.4 KB / 11.7 KB minified

Acts much like Chrome’s Web Inspector console in terms of coloring, layout and design.

If available, mobileConsole shows details for each method: shows the contents of objects and elements and shows error stack trace for all errors. Note that large string properties inside objects will be truncated to 400 characters.

Groups repeating events by displaying a single event message, prefixed with a dot holding a counter that increases with each consecutive repeat.

Displays a link to the file that caused the event, including the line- and column number that triggered it.

Hooks into window.onerror to catch and display (uncatched) JavaScript errors.

Keeps a history of all entered commands in sessionStorage, meaning commands are stored as long as the browser’s tab is opened. Command history can be recalled using up and down arrows on the keyboard (if available), and it also sports an autocomplete-based pop-up, which is especially useful on mobile devices.

Has buttons to toggle the visibility of the logging types (log, trace, info, warn and error) and a button to clear the console completely (no undo).

Can be minimized to ‘dock’ on the underside of the screen; compensates for its own height when maximized (or minimized) by adding (to any existing) padding to the body of the page. This prevents mobileConsole from covering parts of the page.

Download

Usage

Include it as your first script, preferrably as the first line inside your <head> section. You can check the demo page’s source for reference.

Notes

Since it renders as HTML, it needs to have a document.body to render to. As the script is (should be) included before the body is available, it waits for a window load (onload) event before it renders itself. This does not mean you’ll miss some early console calls, though: these will be picked up immediately after the script is included (preferrably placed as the first script in the <head>), and they are displayed as soon as the window is loaded.

As mentioned above; while mobileConsole is active, the reporting of source file and line numbers in the regular console is incorrect (they will all appear to come from somewhere inside hnl.MobileConsole.js, as that is technically triggering the events). Note that source file and line numbers in mobileConsole are correct.

Clicking the link to the caller, will not neatly jump to the corresponding line. But it *will* jump to the file. In a new window! How about that?

Syntax errors will not be logged, only runtime errors. This is by design; JavaScript does not provide a way to hook into syntax errors.

mobileConsole is still being developed; let me know if you run into any bugs, using the comments below!

If mobileConsole doesn’t start (mobile detection fails), you can either override autostart by setting overrideAutorun to true or add the following script to your page:

if (!mobileConsole.status.initialized) {
mobileConsole.init();
}

As of version 1.3.5, mobileConsole can be closed using the ‘X’ at the right-hand side. Two things to note: mobileConsole cannot be rebuilt again until you reload the page, so if the console is ‘in your way’ of viewing content, I suggest you use the minimize button (left-hand side) instead. The other is that, while closed, the script wil still ‘pipe’ the original console‘s logging.

Compatibility

As of version 1.3.3, mobileConsole was tested (and working) on:

iOS Safari (applewebkit 601.1.46 & applewebkit 602.1.50)

Mozilla (5.0)

Firefox (37+) – Note that Firefox/Mozilla reports some events (such as onclick) as coming from line 1, column 1 in the document. I am still looking into why this is.

Chrome (50+)

Internet Explorer (8+) (Trident 4.0+) – IE8 support is flimsy, at best, but it seems to work. Console input is hit-and-miss. Note that IE8 and IE9 do not support a proper stack trace, so no linenumbers and error details are available.

Thank you for this nice little library! I‘m writing to report a potential issue (because your gist page does not seem to allow issue report anyway).

The issue is, although I follow the “Usage” to include the script in my webpage, the console does not show up on my device (which is a non-mainstream Android tablet). It then took a very determined developer to read through the dialogs in your current website to realize: (1) adding a manual init() would do the trick; (2) and your good intention to make it automatic.

But, based on my experience, also based on another similar question asked at the end of your gist page, I suspect the automatic method might not always work on the vast variation of Android devices. Therefore I would suggest you at least mention “users may need to manually call init()” in your Usage section. Thanks for you consideration.

Fair point; the mobile-detection can indeed fail. That’s why I exposed the internal init function, and provided an overrideAutorun variable, forcing it to always run. I realized I had not explained this in the notes, so I just added it. Thanks!

you spent a lot of extra effort – but now the mobileConsole works like a charm! I simply added my extra “if” statement to get rid of those empty messages after opening a group, but everything else worked right out of the box!

it runs now without crashing – and it displays nested objects – well done!

Unfortunately,
– null objects
– empty objects and
– empty arrays
are no longer shown at all – all one can see is a gap and an increased line height

I can understand if gets annoying now – you already did a lot of work – but personally, I may be able to live with the first nesting level of an object only, but I cannot forgive not showing empty arrays and null values!

Please, tell me if you decide not to continue enhancing your mobileConsole: I will then make my personal version of it for my own purpose.

It works now. It was evaluating some value types (empty arrays, objects, null and undefined) as objects, creating empty tables. See the gist for 1.3.2, and let me know if this fixes it for you!

I am planning on modifying the display of elements (logging an element shows only the outer most tags, but you can’t expand them, as in the regular console) and then I will leave it alone for a while. Until someone asks for improvements again 😉

Nice to hear! If you want, you can try updating to 1.3.0 (just updated) which fixes a lot of small bugs, and fills in some missing polyfills. Perhaps this version will work for you straight out of the box!

I found it: the problem is in “htmlToString(html)”, where you call “String(html)” – if you provide “Object.create(null)” (which may happen if you “console.log” such an object), a TypeError is thrown on my iPad.

That’s an interesting finding I will have to consider in my code as well!

If it launches without initing it, then the addition of ‘ipad’ to the navigator check works. I designed mobileConsole to start automatically, as it is meant to be fire and forget (just add the js to the page, without further configuration necessary, and it will launch automatically on mobile devices such as the ipad). overrideAutorun will make it run always; even on desktop browsers – which is usually not the desired effect.

Is the ‘no default value’ error logged inside mobileConsole? Then that would indicate that it works, and perhaps the error is originating from another script. Is it reporting a file + line and column number as the origin?

Thanks a lot for the quick fix – I just ran a very first test, here are my outcomes:
– I no longer seem to be able to log objects, instead I now get an “(Empty String)”
– after starting a new group I also get this “(Empty String)” message. In my opinion, the new group should just be started, without any additional output
– well, the new “Note: this method is not supported on…original console” is not really necessary, isn’t it? If you decide to keep it, I will simply “polyfill” missing console functions with dummies just to avoid the message

One last remark: I did not have the time to look into your object -> string conversion, but on my Android phone, it throws an error (and on my iPad it now results in “undefined”)

I really don’t understand how the object logger suddenly broke down, and I can’t replicate it here. I didn’t touch this part (objectToString) in my update.
The same goes for the group method; not touched by my update.
Can you check if it happens on the demo page as well?

– Fair point on the note, I have removed it.
– Also added ‘ipad’ to the user agent string detection, somehow it was missing, perhaps this will fix the autostart for you. If not, just set 'overrideAutorun' (currently at line 97) to true.
– I also included the function.bind polyfill, which I forgot in 1.2.7

– not far below “case ‘group’: case ‘groupCollapsed’: case ‘groupEnd’:” I had to remove the line “msgContainer.innerHTML = ‘‘ + message + ‘‘;” as “message” seems to be udnefined;
– “originalConsole.clear” is not always available, thus, I added a check “if (typeof originalConsole.clear === ‘function’)” before actually calling it
But now, the mobileConsole works fine on my old iPad!

Hi Andreas, thanks for you useful feedback! I will need to revise the code, as you have pointed out quite a big coding flaw, in that I do check if the original console functions are present, but later on I don’t re-check if they are available to use (at least, that is my assumption, will have to look into the code).

And that undefined message… ouch!

Cheers, I will look into it soon, and glad you got it to work and it was of use to you!

Well, I had some time on my hands so I fixed the bugs you mentioned. I don’t have the same device as you, so I can’t be sure, but fixed is:

– When evaluating the device’s console methods, it returns a function when no method is found. This function simply logs 'Note: this method is not supported on this device's original console' to the console.
– Checking for an empty message has been improved, as somehow I never thought of checking if it was undefined.
– Undefined evaluations have all been modified (typeof var === 'undefined' instead of var === undefined)

Thank you very much for your effort – it’s very helpful for WebApp debugging on older devices (such as a 1st generation iPad or a Smartphone running Android 4.1). However, I additionally had to provide a polyfill for “Function.prototype.bind” and mobileConsole.init() “manually” since “isMobile()” failed for my old iPad. You may contact me for further details, if you like.

hello, i really appreciated what you have created here. i have found that i cannot clear the console by clicking the clear button on firefox for android. the same code will however run on chrome, am i doing something wrong?