Hacking Mountain Lion: Bringing the old Web Inspector back 2012-08-27

The problem

In Mountain Lion, Apple introduced a new Web Inspector for Safari. However, the new inspector comes with a horrible UI. It features many small icons that are hard to differentiate. Compared to the old inspector, it takes two more clicks to open the console and two more clicks to look at HTTP requests (after having successfully deciphered the icons). By default, the new inspector also unexpectedly breaks on exceptions, which is very confusing. The network requests pane does not let you see what request method was used for a particular request and does not show you the request body that was sent, making it very hard to find a POST request and debug it.

Hacking around

It turns out that the WebKit Nightly builds have an option in the Developer menu, called Use WebKit Web Inspector. Selecting this option solves the problem and brings the old inspector back. However, this only works in the nightly Safari. Not helpful for my case, because I was developing a Cocoa application and wanted to use the WebKit inspector in one of its WebViews.

Naturally, I used dtrace to see what was going on:

% cat inspector.d
pid$target::*nspector*:entry {}
pid$target::*nspector*:return {}

% sudo dtrace -s inspector.d -F -c /Applications/Safari.app/Contents/MacOS/SafariForWebKitDevelopment

The basic syntax of the dtrace script is pid:class-name:method-name:entry/return, and details can be found in man dtrace. Here, the command launches Safari and listens on any Objective-C messages that contain the string nspector.

After clicking around, here's what it found:

  0  <- -[NSWindow(NSInspectorBarSupport) inspectorBar] 
  0  -> -[DevelopMenuController useWebKitWebInspector] 
  0    -> Safari::WK::Preferences::inspectorUsesWebKitUserInterface() const 
  0      -> WKPreferencesGetInspectorUsesWebKitUserInterface 
  0        -> WebKit::WebPreferences::inspectorUsesWebKitUserInterface() const 
  0          -> WebKit::WebPreferencesKey::inspectorUsesWebKitUserInterfaceKey() 
  0          <- WebKit::WebPreferencesKey::inspectorUsesWebKitUserInterfaceKey() 
  0        <- WebKit::WebPreferences::inspectorUsesWebKitUserInterface() const 
  0      <- WKPreferencesGetInspectorUsesWebKitUserInterface 
  0    <- Safari::WK::Preferences::inspectorUsesWebKitUserInterface() const 
  0  <- -[DevelopMenuController useWebKitWebInspector] 
  0  -> Safari::BrowserContentViewController::canShowInspector() const 
  0  <- Safari::BrowserContentViewController::canShowInspector() const 
  0  -> -[NSWindow(NSInspectorBarSupport) inspectorBar] 

Now we need to find a way for other Cocoa applications to use the the old inspector. Thankfully, WebKit is open source. After searching for the keywords, an interesting code file came up which contains the following eye-catching function:

static bool useWebKitWebInspector()
{
    // Call the soft link framework function to dlopen it, then [NSBundle bundleWithIdentifier:] will work.
    WebInspectorLibrary();

    if (![[NSBundle bundleWithIdentifier:@"com.apple.WebInspector"] pathForResource:@"Main" ofType:@"html"])
        return true;

    if (![[NSBundle bundleWithIdentifier:@"com.apple.WebCore"] pathForResource:@"inspector" ofType:@"html" inDirectory:@"inspector"])
        return false;

    return [[NSUserDefaults standardUserDefaults] boolForKey:@"UseWebKitWebInspector"];
}

After trying the obvious things, which is was defaults write -g UseWebKitWebInspector -bool YES, which didn't do anything, as well as moving /System/Library/PrivateFrameworks/WebInspector.framework/Resources/Main.html to a different place, which broke Safari, I figured that I needed to install a newer version of WebKit on my computer.

The solution

Installing the new WebKit from the nightly build system-wide wasn't too difficult. After a bit of trial and error (mainly using grep to identify missing symbols in the frameworks based on Safari's crash tracebacks), the following sequence did the trick:

% cd /System/Library/Frameworks
% sudo mv WebKit.framework WebKit.framework.old
% sudo cp  -a /Applications/WebKit.app/Contents/Frameworks/10.8/WebKit.framework .
% sudo mkdir -p WebKit.framework/Versions/A/Frameworks
% sudo cp -a /Applications/WebKit.app/Contents/Frameworks/10.8/WebCore.framework WebKit.framework/Versions/A/Frameworks
% sudo mv JavaScriptCore.framework JavaScriptCore.framework.old
% sudo cp -a /Applications/WebKit.app/Contents/Frameworks/10.8/JavaScriptCore.framework .
% cd /System/Library/PrivateFrameworks
% sudo mv WebKit2.framework WebKit2.framework.old
% sudo cp  -a /Applications/WebKit.app/Contents/Frameworks/10.8/WebKit2.framework .

After that, all that needed to be done was setting the global preference:

% defaults write -g UseWebKitWebInspector -bool YES

Now every Cocoa app uses the old WebKit inspector, including the original Safari. Problem solved.

 

What are other things in Mountain Lion that annoy you and that you would like to hack?


This article is also available in Serbo-Croatian. Thanks to Jovana Milutinovich for translating!


Comments (18)

jsguru says: 2013-04-05

Hey this works well, but when I try to debug remote session my iPad it still uses the default web inspector. Is there a way to change that too ?

Daryl says: 2012-11-27

Does anyone know if there are any stable non-safari builds of WebKit?

primalmotion says: 2012-10-22

Well this mean that you change the WebKit Framework for the whole OS. I really hope for you it won't break anything else. Tons of system and third party apps rely on this framework.

kemenaran says: 2012-10-16

> I'd love to see a hack or setting to speed up screen animation
> between full screen apps. That basically makes them useless
> for me when there's so much potential.

I really agree on this one: this animation at the end of the switch between spaces, where the screens go slooowly in place before gaining focus, is driving me mad.

I tried to hack around this, looking for User Defaults strings in the binary, but found nothing. I'm sure there is a way though.

marsala says: 2012-10-16

I'd like to get the pronunciation transcriptions in the Spotlight dictionary results back!

lucian303 says: 2012-10-16

I'd love to see a hack or setting to speed up screen animation between full screen apps. That basically makes them useless for me when there's so much potential.

Kyle Fox says: 2012-10-16

Wow, very handy! I *hate* the new Web Inspector in Safari, for the exact reasons you outline. Luckily Chrome still sports the more usable version.

It would be *awesome* bundle this functionality into a Mac app that would let less-technical folks toggle this feature on & off :)

NotATerrorist says: 2012-10-16

Hey, I don't mean to high-jack your super cool hack but why does your blog not have a RSS feed. Wanted to add you to my Google Reader so I can read your future blogs but no rss feed...

Thx for the cool hack.

Thomas says: 2012-09-21

Remember to use @Phil Freo's uninstall script before you upgrade to 10.8.2! Alternatively, if you already upgraded and all WebKit based apps crash, just repeat the procedure with the latest WebKit (using a different postfix instead of ".old" so you can distinguish the versions).

Chad says: 2012-09-03

Thanks for this. Agreed that the new inspector isn't so hot. Wishing there was a more permanent fix that could be used on Safari as well...

Dimitris says: 2012-09-02

Thanks for this...

Do you think there's a way to bring back the Activity Monitor window?

reactor says: 2012-09-02

@Phil Freo yep — i am using webkit.app as my default browser, simple as that.

It provides same experience as release safari (except it does not support icloud tabs) and no chance of _system_ breakage from unstable nightly code.

As for “I didn't have any issues using the recent nightly builds of WebKit” — just had something like five crashes. Of course some builds are more stable than others but, well that builds got replaced with updates which you need to install because usually even if they do not break, they have a bunch of other stupid bugs (for example, with scrolling UI).

Pretty tired of these crashes ☹. I want to thank web inspector developers for this unusable crap and already thinking of moving to firefox 17/18 when it’ll be released (will have new cool inspector).

Yoosuf says: 2012-09-02

Woow, it is super cool hack

Phil Freo says: 2012-08-31

To undo these changes:

# Undo these changes
cd /System/Library/PrivateFrameworks
sudo mv WebKit2.framework WebKit2.framework.new
sudo mv WebKit2.framework.old WebKit2.framework
cd /System/Library/Frameworks
sudo mv JavaScriptCore.framework JavaScriptCore.framework.new
sudo mv JavaScriptCore.framework.old JavaScriptCore.framework
sudo mv WebKit.framework/Versions/A/Frameworks WebKit.framework/Versions/A/Frameworks.new
sudo mv WebKit.framework WebKit.framework.new
sudo mv WebKit.framework.old WebKit.framework

Phil Freo says: 2012-08-31

@reactor do you have a better solution? because the new inspector is so bad "putting up with it" isn't one.

Thomas says: 2012-08-30

@reactor:

1) Yes, it might break. Let's hope that Apple includes a new WebKit version in a future OS X update that supports the UseWebKitWebInspector preference so replacing WebKit is no longer necessary.

2) While you're right that nightlies are usually not very stable, I didn't have any issues using the recent nightly builds of WebKit.

While not perfect, for me as a developer replacing WebKit is still a superior solution.

reactor says: 2012-08-29

Some thoughts:

1. This will break with OS X updates.
2. WebKit.app is buggy and crashes often so solution might make all webkit-based apps crash often.

frytaz says: 2012-08-27

Woah thanks for sharing this info, new web inspector in safari driving me crazy :D


Leave a comment


↩ Back to homepage