There are two types of anchor tag requests:
1. Has no target attribute
2. Has a target attribute that should launch a new Mobile Safari window
For request type (1), the UIWebViewDelegate gets one NSURLRequest with navigationType UIWebViewNavigationTypeLinkClicked
For request type (2), the UIWebViewDelegate gets two NSURLRequests with the first being navigationType UIWebViewNavigationTypeLinkClicked, then the second with navigationType UIWebViewNavigationTypeOther
It is this two request process that prevents this issue from being an easy fix - since at the first request, the NSURLRequest can be rejected before we can process it for the second request (which differentiates it at being target="_blank"), where it can be accepted.
How do I differentiate between the two types of anchor tags then, to fix this issue? You can't, not easily. This would require saving state (the request) when a UIWebViewNavigationTypeLinkClicked navigationType is encountered, waiting for a set interval then seeing if a request with navigationType UIWebViewNavigationTypeOther follows suit. If it doesn't, process the NSURLRequest normally. If it does, punt it to Mobile Safari. This can potentially be error prone.
I think what needs to happen is a change in the behaviour for handling anchor tags.
Here's what I propose:
If it's an anchor tag with NO target attribute - it can ONLY load file urls, no http urls. Thus only local files can be loaded in the UIWebView in this situation.
If it's an anchor tag WITH a target attribute - it can ONLY load external http urls, no file urls (besides Mobile Safari won't display any file urls). Thus only external files can be loaded in Mobile Safari in this situation.
With this new policy, all requests with navigationTypes of UIWebViewNavigationTypeLinkClicked, we need to wait for a subsequent request of navigationType UIWebViewNavigationTypeOther, always (and always return NO on this first request, if not the NSURLProtocol handler will kick in and reject it anyway).
If we don't receive the subsequent request (within a set interval) - we reject the request (return NO). If we receive the subsequent request, we process it for the whitelist normally.
This will not apply to child iframes because we detect that the request is from an iframe, and iframe requests can load external urls (if they pass the whitelist). This proposed new policy only applies to the main page loaded by the UIWebView.
Because of the complexity of this, this can't make it in 1.6.0