Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Flash in Cocoa WebView

In my Cocoa app, I want to prevent Flash from loading in a WebView, and let the user decide if the Flash should be shown for each page. (That's the same behavior already available through the ClickToFlash plugin or Safari extension. Bundling any of those extensions is probably not an option because of licensing issues.)

Unfortunately most of the Flash I'm trying to avoid is generated from embedded JavaScript specifically designed to prevent easy flash blocking, so I cannot filter the raw HTML for inclusion of Flash objects.

Also, I cannot disable JavaScript for my WebView, as the page I want to display looks completely different when JavaScript is turned off.

Is there a notification/hook I can use to modify the page DOM after JavaScript has been executed, but before the Flash plugin is loaded?

Or should I pursue a different direction?

Thanks, Ilja

like image 433
iljawascoding Avatar asked Feb 03 '11 11:02

iljawascoding


2 Answers

Ideally, you would just define your own WebKit plug-in that handles the application/shockwave-flash MIME type and make your plug-in do nothing.

However, there is unfortunately no way to control the priority of multiple WebKit plug-ins that all register for the same MIME type. The loading order of WebKit plug-ins is totally random and arbitrary, so you cannot guarantee that your plug-in will handle the Flash object instead of the Flash plug-in.

The only way around this that I've found is to subclass WebView and override the private method -_pluginForMIMEType: like so:

@class WebBasePluginPackage;

@interface WebView ( MyFlashPluginHack )
- (WebBasePluginPackage *)_pluginForMIMEType:(NSString *)MIMEType;
@end

@implementation MyWebView

- (WebBasePluginPackage *)_pluginForMIMEType:(NSString *)MIMEType
{
    if ( [MIMEType isEqualToString:@"application/x-shockwave-flash"] )
    {
        return [super _pluginForMIMEType:@"application/my-plugin-type"];
    }
        else
    {
        return [super _pluginForMIMEType:MIMEType];
    }
}

@end

Then you just need to create a custom WebKit plugin to handle "application/my-plugin-type" and have that plug-in do nothing at all.

like image 67
Rob Keniger Avatar answered Nov 15 '22 00:11

Rob Keniger


Okay, we pretty much figured this out.

Since there is no official API that lets the host app know when JavaScript has finished or control what plugin should load, we are now using custom JavaScript that gets inserted into the received HTML we want to display.

The ClickToFlash Safari extension (not the Internet plugin, which it is based on) was a good inspiration.

like image 40
iljawascoding Avatar answered Nov 15 '22 01:11

iljawascoding