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 W开发者_如何学编程ebView, 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
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.
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.
精彩评论