WebCore:
authorthatcher <thatcher@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Sep 2007 20:43:50 +0000 (20:43 +0000)
committerthatcher <thatcher@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Sep 2007 20:43:50 +0000 (20:43 +0000)
        Reviewed by Darin.

        Changed the blocked exception log message to match AppKit's blocked exception message.

        * platform/mac/BlockExceptions.mm:
        (ReportBlockedObjCException):

WebKit:

        Reviewed by Darin.

        <rdar://problem/5443883> Uncaught Objective-C exceptions in WebKit clients lead to hard-to-diagnose crashes

        Changed all the direct delegate calls to use helper functions that have direct access to
        WebView's delegate objects. These helper methods will catch any ObjC exceptions and call
        ReportDiscardedDelegateException to log the discarded exception. WebView's that have
        catchesDelegateExceptions set to NO will not pay the cost of a @try/@catch. The delegate
        forwarders also have the same behavior.

        * Misc/WebKitLogging.h:
        * Misc/WebKitLogging.m:
        (ReportDiscardedDelegateException):
        * Plugins/WebBaseNetscapePluginView.mm:
        (-[WebBaseNetscapePluginView loadPluginRequest:]):
        * Plugins/WebNullPluginView.mm:
        (-[WebNullPluginView viewDidMoveToWindow]):
        * WebCoreSupport/WebChromeClient.mm:
        (WebChromeClient::createWindow):
        (WebChromeClient::createModalDialog):
        (WebChromeClient::runModal):
        (WebChromeClient::toolbarsVisible):
        (WebChromeClient::statusbarVisible):
        (WebChromeClient::addMessageToConsole):
        (WebChromeClient::canRunBeforeUnloadConfirmPanel):
        (WebChromeClient::runBeforeUnloadConfirmPanel):
        (WebChromeClient::runJavaScriptAlert):
        (WebChromeClient::runJavaScriptConfirm):
        (WebChromeClient::runJavaScriptPrompt):
        (WebChromeClient::shouldInterruptJavaScript):
        (WebChromeClient::setStatusbarText):
        (WebChromeClient::print):
        * WebCoreSupport/WebContextMenuClient.mm:
        (WebContextMenuClient::getCustomMenuFromDefaultItems):
        (WebContextMenuClient::contextMenuItemSelected):
        * WebCoreSupport/WebDragClient.mm:
        (WebDragClient::startDrag):
        * WebCoreSupport/WebEditorClient.mm:
        (WebEditorClient::textFieldDidBeginEditing):
        (WebEditorClient::textFieldDidEndEditing):
        (WebEditorClient::textDidChangeInTextField):
        (WebEditorClient::doTextFieldCommandFromEvent):
        (WebEditorClient::textWillBeDeletedInTextField):
        (WebEditorClient::textDidChangeInTextArea):
        * WebCoreSupport/WebFrameBridge.mm:
        (-[WebFrameBridge viewForPluginWithFrame:URL:attributeNames:attributeValues:MIMEType:DOMElement:loadManually:]):
        * WebCoreSupport/WebFrameLoaderClient.mm:
        (WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache):
        (WebFrameLoaderClient::assignIdentifierToInitialRequest):
        (WebFrameLoaderClient::dispatchWillSendRequest):
        (WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge):
        (WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge):
        (WebFrameLoaderClient::dispatchDidReceiveResponse):
        (WebFrameLoaderClient::willCacheResponse):
        (WebFrameLoaderClient::dispatchDidReceiveContentLength):
        (WebFrameLoaderClient::dispatchDidFinishLoading):
        (WebFrameLoaderClient::dispatchDidFailLoading):
        (WebFrameLoaderClient::dispatchDidHandleOnloadEvents):
        (WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad):
        (WebFrameLoaderClient::dispatchDidCancelClientRedirect):
        (WebFrameLoaderClient::dispatchWillPerformClientRedirect):
        (WebFrameLoaderClient::dispatchDidChangeLocationWithinPage):
        (WebFrameLoaderClient::dispatchWillClose):
        (WebFrameLoaderClient::dispatchDidReceiveIcon):
        (WebFrameLoaderClient::dispatchDidStartProvisionalLoad):
        (WebFrameLoaderClient::dispatchDidReceiveTitle):
        (WebFrameLoaderClient::dispatchDidCommitLoad):
        (WebFrameLoaderClient::dispatchDidFailProvisionalLoad):
        (WebFrameLoaderClient::dispatchDidFailLoad):
        (WebFrameLoaderClient::dispatchDidFinishDocumentLoad):
        (WebFrameLoaderClient::dispatchDidFinishLoad):
        (WebFrameLoaderClient::dispatchDidFirstLayout):
        (WebFrameLoaderClient::dispatchCreatePage):
        (WebFrameLoaderClient::dispatchUnableToImplementPolicy):
        (WebFrameLoaderClient::dispatchWillSubmitForm):
        (WebFrameLoaderClient::dispatchDidLoadMainResource):
        * WebView/WebHTMLView.mm:
        (-[WebHTMLView callDelegateDoCommandBySelectorIfNeeded:]):
        (-[WebHTMLView validateUserInterfaceItem:]):
        * WebView/WebPDFView.mm:
        (-[WebPDFView validateUserInterfaceItem:]):
        (-[WebPDFView PDFViewSavePDFToDownloadFolder:]):
        * WebView/WebView.mm:
        (-[WebView _openNewWindowWithRequest:]):
        (-[WebView _menuForElement:defaultItems:]):
        (-[WebView _mouseDidMoveOverElement:modifierFlags:]):
        (-[WebView _cacheResourceLoadDelegateImplementations]):
        (-[WebView _cacheFrameLoadDelegateImplementations]):
        (-[WebView _policyDelegateForwarder]):
        (-[WebView _UIDelegateForwarder]):
        (-[WebView _editingDelegateForwarder]):
        (-[WebView _scriptDebugDelegateForwarder]):
        (-[WebView _setCatchesDelegateExceptions:]):
        (-[WebView _catchesDelegateExceptions]):
        (-[_WebSafeForwarder initWithTarget:defaultTarget:]):
        (-[_WebSafeForwarder forwardInvocation:]):
        (-[_WebSafeForwarder methodSignatureForSelector:]):
        (-[WebView _commonInitializationWithFrameName:groupName:]):
        (-[WebView validateUserInterfaceItem:]):
        (-[WebView _headerHeight]):
        (-[WebView _footerHeight]):
        (-[WebView _drawHeaderInRect:]):
        (-[WebView _drawFooterInRect:]):
        (-[WebView _shouldChangeSelectedDOMRange:toDOMRange:affinity:stillSelecting:]):
        (CallDelegate):
        (CallDelegateReturningFloat):
        (CallDelegateReturningBoolean):
        (CallUIDelegate):
        (CallUIDelegateReturningFloat):
        (CallUIDelegateReturningBoolean):
        (CallFrameLoadDelegate):
        (CallResourceLoadDelegate):
        (CallFormDelegate):
        (CallFormDelegateReturningBoolean):
        * WebView/WebViewInternal.h:
        * WebView/WebViewPrivate.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@25396 268f45cc-cd09-0410-ab3c-d52691b4dbfc

18 files changed:
WebCore/ChangeLog
WebCore/platform/mac/BlockExceptions.mm
WebKit/ChangeLog
WebKit/Misc/WebKitLogging.h
WebKit/Misc/WebKitLogging.m
WebKit/Plugins/WebBaseNetscapePluginView.mm
WebKit/Plugins/WebNullPluginView.mm
WebKit/WebCoreSupport/WebChromeClient.mm
WebKit/WebCoreSupport/WebContextMenuClient.mm
WebKit/WebCoreSupport/WebDragClient.mm
WebKit/WebCoreSupport/WebEditorClient.mm
WebKit/WebCoreSupport/WebFrameBridge.mm
WebKit/WebCoreSupport/WebFrameLoaderClient.mm
WebKit/WebView/WebHTMLView.mm
WebKit/WebView/WebPDFView.mm
WebKit/WebView/WebView.mm
WebKit/WebView/WebViewInternal.h
WebKit/WebView/WebViewPrivate.h

index e5e8efc3bb0121b2a1a2c1e82c17b0292c20676c..244145cf2b25052a064049158bdc07c9c652b864 100644 (file)
@@ -1,3 +1,12 @@
+2007-09-05  Timothy Hatcher  <timothy@apple.com>
+
+        Reviewed by Darin.
+
+        Changed the blocked exception log message to match AppKit's blocked exception message.
+
+        * platform/mac/BlockExceptions.mm:
+        (ReportBlockedObjCException):
+
 2007-09-06  Darin Adler  <darin@apple.com>
 
         Reviewed by Hyatt.
index 0ce50d7776e2f93a44d39eb1af98819b19ef7ff0..f2dc1ec15bf708b301cfda5ecc43a3d4f8ee7f27 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #import <wtf/Assertions.h>
 
-void ReportBlockedObjCException(NSException *localException)
+void ReportBlockedObjCException(NSException *exception)
 {
 #if ASSERT_DISABLED
-    NSLog(@"Uncaught exception - %@\n", localException);
+    NSLog(@"*** WebKit discarding exception: <%@> %@", [exception name], [exception reason]);
 #else
-    ASSERT_WITH_MESSAGE(0, "Uncaught exception - %@", localException);
+    ASSERT_WITH_MESSAGE(0, "Uncaught exception - %@", exception);
 #endif
 }
index ef7c73b16216db73282fcb173d8ee8a9c7a79dad..3dd2ad83869c5ec6e867505645e552673c719359 100644 (file)
@@ -1,3 +1,122 @@
+2007-09-05  Timothy Hatcher  <timothy@apple.com>
+
+        Reviewed by Darin.
+
+        <rdar://problem/5443883> Uncaught Objective-C exceptions in WebKit clients lead to hard-to-diagnose crashes
+
+        Changed all the direct delegate calls to use helper functions that have direct access to
+        WebView's delegate objects. These helper methods will catch any ObjC exceptions and call
+        ReportDiscardedDelegateException to log the discarded exception. WebView's that have
+        catchesDelegateExceptions set to NO will not pay the cost of a @try/@catch. The delegate
+        forwarders also have the same behavior.
+
+        * Misc/WebKitLogging.h:
+        * Misc/WebKitLogging.m:
+        (ReportDiscardedDelegateException):
+        * Plugins/WebBaseNetscapePluginView.mm:
+        (-[WebBaseNetscapePluginView loadPluginRequest:]):
+        * Plugins/WebNullPluginView.mm:
+        (-[WebNullPluginView viewDidMoveToWindow]):
+        * WebCoreSupport/WebChromeClient.mm:
+        (WebChromeClient::createWindow):
+        (WebChromeClient::createModalDialog):
+        (WebChromeClient::runModal):
+        (WebChromeClient::toolbarsVisible):
+        (WebChromeClient::statusbarVisible):
+        (WebChromeClient::addMessageToConsole):
+        (WebChromeClient::canRunBeforeUnloadConfirmPanel):
+        (WebChromeClient::runBeforeUnloadConfirmPanel):
+        (WebChromeClient::runJavaScriptAlert):
+        (WebChromeClient::runJavaScriptConfirm):
+        (WebChromeClient::runJavaScriptPrompt):
+        (WebChromeClient::shouldInterruptJavaScript):
+        (WebChromeClient::setStatusbarText):
+        (WebChromeClient::print):
+        * WebCoreSupport/WebContextMenuClient.mm:
+        (WebContextMenuClient::getCustomMenuFromDefaultItems):
+        (WebContextMenuClient::contextMenuItemSelected):
+        * WebCoreSupport/WebDragClient.mm:
+        (WebDragClient::startDrag):
+        * WebCoreSupport/WebEditorClient.mm:
+        (WebEditorClient::textFieldDidBeginEditing):
+        (WebEditorClient::textFieldDidEndEditing):
+        (WebEditorClient::textDidChangeInTextField):
+        (WebEditorClient::doTextFieldCommandFromEvent):
+        (WebEditorClient::textWillBeDeletedInTextField):
+        (WebEditorClient::textDidChangeInTextArea):
+        * WebCoreSupport/WebFrameBridge.mm:
+        (-[WebFrameBridge viewForPluginWithFrame:URL:attributeNames:attributeValues:MIMEType:DOMElement:loadManually:]):
+        * WebCoreSupport/WebFrameLoaderClient.mm:
+        (WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache):
+        (WebFrameLoaderClient::assignIdentifierToInitialRequest):
+        (WebFrameLoaderClient::dispatchWillSendRequest):
+        (WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge):
+        (WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge):
+        (WebFrameLoaderClient::dispatchDidReceiveResponse):
+        (WebFrameLoaderClient::willCacheResponse):
+        (WebFrameLoaderClient::dispatchDidReceiveContentLength):
+        (WebFrameLoaderClient::dispatchDidFinishLoading):
+        (WebFrameLoaderClient::dispatchDidFailLoading):
+        (WebFrameLoaderClient::dispatchDidHandleOnloadEvents):
+        (WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad):
+        (WebFrameLoaderClient::dispatchDidCancelClientRedirect):
+        (WebFrameLoaderClient::dispatchWillPerformClientRedirect):
+        (WebFrameLoaderClient::dispatchDidChangeLocationWithinPage):
+        (WebFrameLoaderClient::dispatchWillClose):
+        (WebFrameLoaderClient::dispatchDidReceiveIcon):
+        (WebFrameLoaderClient::dispatchDidStartProvisionalLoad):
+        (WebFrameLoaderClient::dispatchDidReceiveTitle):
+        (WebFrameLoaderClient::dispatchDidCommitLoad):
+        (WebFrameLoaderClient::dispatchDidFailProvisionalLoad):
+        (WebFrameLoaderClient::dispatchDidFailLoad):
+        (WebFrameLoaderClient::dispatchDidFinishDocumentLoad):
+        (WebFrameLoaderClient::dispatchDidFinishLoad):
+        (WebFrameLoaderClient::dispatchDidFirstLayout):
+        (WebFrameLoaderClient::dispatchCreatePage):
+        (WebFrameLoaderClient::dispatchUnableToImplementPolicy):
+        (WebFrameLoaderClient::dispatchWillSubmitForm):
+        (WebFrameLoaderClient::dispatchDidLoadMainResource):
+        * WebView/WebHTMLView.mm:
+        (-[WebHTMLView callDelegateDoCommandBySelectorIfNeeded:]):
+        (-[WebHTMLView validateUserInterfaceItem:]):
+        * WebView/WebPDFView.mm:
+        (-[WebPDFView validateUserInterfaceItem:]):
+        (-[WebPDFView PDFViewSavePDFToDownloadFolder:]):
+        * WebView/WebView.mm:
+        (-[WebView _openNewWindowWithRequest:]):
+        (-[WebView _menuForElement:defaultItems:]):
+        (-[WebView _mouseDidMoveOverElement:modifierFlags:]):
+        (-[WebView _cacheResourceLoadDelegateImplementations]):
+        (-[WebView _cacheFrameLoadDelegateImplementations]):
+        (-[WebView _policyDelegateForwarder]):
+        (-[WebView _UIDelegateForwarder]):
+        (-[WebView _editingDelegateForwarder]):
+        (-[WebView _scriptDebugDelegateForwarder]):
+        (-[WebView _setCatchesDelegateExceptions:]):
+        (-[WebView _catchesDelegateExceptions]):
+        (-[_WebSafeForwarder initWithTarget:defaultTarget:]):
+        (-[_WebSafeForwarder forwardInvocation:]):
+        (-[_WebSafeForwarder methodSignatureForSelector:]):
+        (-[WebView _commonInitializationWithFrameName:groupName:]):
+        (-[WebView validateUserInterfaceItem:]):
+        (-[WebView _headerHeight]):
+        (-[WebView _footerHeight]):
+        (-[WebView _drawHeaderInRect:]):
+        (-[WebView _drawFooterInRect:]):
+        (-[WebView _shouldChangeSelectedDOMRange:toDOMRange:affinity:stillSelecting:]):
+        (CallDelegate):
+        (CallDelegateReturningFloat):
+        (CallDelegateReturningBoolean):
+        (CallUIDelegate):
+        (CallUIDelegateReturningFloat):
+        (CallUIDelegateReturningBoolean):
+        (CallFrameLoadDelegate):
+        (CallResourceLoadDelegate):
+        (CallFormDelegate):
+        (CallFormDelegateReturningBoolean):
+        * WebView/WebViewInternal.h:
+        * WebView/WebViewPrivate.h:
+
 2007-09-04  Timothy Hatcher  <timothy@apple.com>
 
         Reviewed by Darin.
index edaaa5af0dd78180e8af87974bcd9db3ad4db630..0bf791c7d872dda99bff8a214d1c3a0bff8ccecc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2005, 2007 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -78,6 +78,7 @@ while (0)
 #define ASSERT_MAIN_THREAD() ((void)0)
 #endif
 
+void ReportDiscardedDelegateException(SEL delegateSelector, id exception);
 
 #ifdef __cplusplus
 }
index fbac3fa5ce07adbb90f5251c5eb39f9b762080de..4e4294fc0bb0e21fae5c998fb4435990126e530b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2005, 2007 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -103,3 +103,13 @@ BOOL WebKitRunningOnMainThread()
 {
     return pthread_main_np() != 0;
 }
+
+void ReportDiscardedDelegateException(SEL delegateSelector, id exception)
+{
+    if ([exception isKindOfClass:[NSException class]])
+        NSLog(@"*** WebKit discarded an uncaught exception in the %s delegate: <%@> %@",
+            sel_getName(delegateSelector), [exception name], [exception reason]);
+    else
+        NSLog(@"*** WebKit discarded an uncaught exception in the %s delegate: %@",
+            sel_getName(delegateSelector), exception);
+}
index b2c97029630051ad8198752287a471b81fec7bd1..fbacc62f75a43b4036be32ba419bf84b80b65f5e 100644 (file)
@@ -2106,15 +2106,9 @@ static OSStatus TSMEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEve
         frame = [[self webFrame] findFrameNamed:frameName];
     
         if (frame == nil) {
-            WebView *newWebView = nil;
             WebView *currentWebView = [self webView];
-            id wd = [currentWebView UIDelegate];
-            if ([wd respondsToSelector:@selector(webView:createWebViewWithRequest:)]) {
-                newWebView = [wd webView:currentWebView createWebViewWithRequest:nil];
-            } else {
-                newWebView = [[WebDefaultUIDelegate sharedUIDelegate] webView:currentWebView createWebViewWithRequest:nil];
-            }
-            
+            WebView *newWebView = CallUIDelegate(currentWebView, @selector(webView:createWebViewWithRequest:), nil);
+
             if (!newWebView) {
                 if ([pluginRequest sendNotification]) {
                     [self willCallPlugInFunction];
index 118403574c407811ac7b0ec189fe768e74fd0670..2e7d372dec55b2a88a12a7aa29d5550640907b69 100644 (file)
@@ -71,15 +71,15 @@ static NSImage *image = nil;
 
 - (void)viewDidMoveToWindow
 {
-    if(!didSendError && _window && error){
+    if (!didSendError && _window && error) {
         didSendError = YES;
         WebFrame *webFrame = kit(core(element)->document()->frame());
         WebView *webView = [webFrame webView];
         WebDataSource *dataSource = [webFrame _dataSource];
 
-        id resourceLoadDelegate = [webView resourceLoadDelegate];
-        if ([resourceLoadDelegate respondsToSelector:@selector(webView:plugInFailedWithError:dataSource:)])
-            [resourceLoadDelegate webView:webView plugInFailedWithError:error dataSource:dataSource];
+        WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
+        if (implementations.plugInFailedWithErrorFunc)
+            CallResourceLoadDelegate(implementations.plugInFailedWithErrorFunc, webView, @selector(webView:plugInFailedWithError:dataSource:), error, dataSource);
     }
 }
 
index 4f337e5386168230e6d765410aaa23916104e3d8..d78c9d9785052dd6668f39d1717aa60f7169ddec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
  * Copyright (C) 2007 Trolltech ASA
  *
  * Redistribution and use in source and binary forms, with or without
@@ -136,14 +136,7 @@ Page* WebChromeClient::createWindow(Frame*, const FrameLoadRequest& request)
     NSURLRequest *URLRequest = nil;
     if (!request.isEmpty())
         URLRequest = request.resourceRequest().nsURLRequest();
-
-    WebView *newWebView;
-    id delegate = [m_webView UIDelegate];
-    if ([delegate respondsToSelector:@selector(webView:createWebViewWithRequest:)])
-        newWebView = [delegate webView:m_webView createWebViewWithRequest:URLRequest];
-    else
-        newWebView = [[WebDefaultUIDelegate sharedUIDelegate] webView:m_webView createWebViewWithRequest:URLRequest];
-
+    WebView *newWebView = CallUIDelegate(m_webView, @selector(webView:createWebViewWithRequest:), URLRequest);
     return core(newWebView);
 }
 
@@ -156,12 +149,9 @@ Page* WebChromeClient::createModalDialog(Frame*, const FrameLoadRequest& request
     WebView *newWebView = nil;
     id delegate = [m_webView UIDelegate];
     if ([delegate respondsToSelector:@selector(webView:createWebViewModalDialogWithRequest:)])
-        newWebView = [delegate webView:m_webView createWebViewModalDialogWithRequest:URLRequest];
+        newWebView = CallUIDelegate(m_webView, @selector(webView:createWebViewModalDialogWithRequest:), URLRequest);
     else if ([delegate respondsToSelector:@selector(webView:createWebViewWithRequest:)])
-        newWebView = [delegate webView:m_webView createWebViewWithRequest:URLRequest];
-    else
-        newWebView = [[WebDefaultUIDelegate sharedUIDelegate] webView:m_webView createWebViewWithRequest:URLRequest];
-
+        newWebView = CallUIDelegate(m_webView, @selector(webView:createWebViewWithRequest:), URLRequest);
     return core(newWebView);
 }
 
@@ -177,7 +167,7 @@ bool WebChromeClient::canRunModal()
 
 void WebChromeClient::runModal()
 {
-    [[m_webView UIDelegate] webViewRunModal:m_webView];
+    CallUIDelegate(m_webView, @selector(webViewRunModal:));
 }
 
 void WebChromeClient::setToolbarsVisible(bool b)
@@ -187,10 +177,7 @@ void WebChromeClient::setToolbarsVisible(bool b)
 
 bool WebChromeClient::toolbarsVisible()
 {
-    id delegate = [m_webView UIDelegate];
-    if ([delegate respondsToSelector:@selector(webViewAreToolbarsVisible:)])
-        return [delegate webViewAreToolbarsVisible:m_webView];
-    return [[WebDefaultUIDelegate sharedUIDelegate] webViewAreToolbarsVisible:m_webView];
+    return CallUIDelegateReturningBoolean(NO, m_webView, @selector(webViewAreToolbarsVisible:));
 }
 
 void WebChromeClient::setStatusbarVisible(bool b)
@@ -200,13 +187,9 @@ void WebChromeClient::setStatusbarVisible(bool b)
 
 bool WebChromeClient::statusbarVisible()
 {
-    id delegate = [m_webView UIDelegate];
-    if ([delegate respondsToSelector:@selector(webViewIsStatusBarVisible:)])
-        return [delegate webViewIsStatusBarVisible:m_webView];
-    return [[WebDefaultUIDelegate sharedUIDelegate] webViewIsStatusBarVisible:m_webView];
+    return CallUIDelegateReturningBoolean(NO, m_webView, @selector(webViewIsStatusBarVisible:));
 }
 
-
 void WebChromeClient::setScrollbarsVisible(bool b)
 {
     [[[m_webView mainFrame] frameView] setAllowsScrolling:b];
@@ -236,30 +219,28 @@ void WebChromeClient::setResizable(bool b)
 
 void WebChromeClient::addMessageToConsole(const String& message, unsigned int lineNumber, const String& sourceURL)
 {
-    id wd = [m_webView UIDelegate];
-    if ([wd respondsToSelector:@selector(webView:addMessageToConsole:)]) {
-        NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
-            (NSString *)message, @"message",
-            [NSNumber numberWithInt: lineNumber], @"lineNumber",
-            (NSString *)sourceURL, @"sourceURL",
-            NULL];
-        
-        [wd webView:m_webView addMessageToConsole:dictionary];
-    }    
+    id delegate = [m_webView UIDelegate];
+    SEL selector = @selector(webView:addMessageToConsole:);
+    if (![delegate respondsToSelector:selector])
+        return;
+
+    NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:
+        (NSString *)message, @"message", [NSNumber numberWithUnsignedInt:lineNumber], @"lineNumber",
+        (NSString *)sourceURL, @"sourceURL", NULL];
+
+    CallUIDelegate(m_webView, selector, dictionary);
+
+    [dictionary release];
 }
 
 bool WebChromeClient::canRunBeforeUnloadConfirmPanel()
 {
-    id wd = [m_webView UIDelegate];
-    return [wd respondsToSelector:@selector(webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:)];
+    return [[m_webView UIDelegate] respondsToSelector:@selector(webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:)];
 }
 
 bool WebChromeClient::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
 {
-    id wd = [m_webView UIDelegate];
-    if ([wd respondsToSelector:@selector(webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:)])
-        return [wd webView:m_webView runBeforeUnloadConfirmPanelWithMessage:message initiatedByFrame:kit(frame)];
-    return true;
+    return CallUIDelegateReturningBoolean(true, m_webView, @selector(webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:), message, kit(frame));
 }
 
 void WebChromeClient::closeWindowSoon()
@@ -284,69 +265,68 @@ void WebChromeClient::closeWindowSoon()
 
 void WebChromeClient::runJavaScriptAlert(Frame* frame, const String& message)
 {
-    id wd = [m_webView UIDelegate];
-    // Check whether delegate implements new version, then whether delegate implements old version. If neither,
-    // fall back to shared delegate's implementation of new version.
-    if ([wd respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:)])
-        [wd webView:m_webView runJavaScriptAlertPanelWithMessage:message initiatedByFrame:kit(frame)];
-    else if ([wd respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:)])
-        [wd webView:m_webView runJavaScriptAlertPanelWithMessage:message];
-    else
-        [[WebDefaultUIDelegate sharedUIDelegate] webView:m_webView runJavaScriptAlertPanelWithMessage:message initiatedByFrame:kit(frame)];    
+    id delegate = [m_webView UIDelegate];
+    SEL selector = @selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:);
+    if ([delegate respondsToSelector:selector]) {
+        CallUIDelegate(m_webView, selector, message, kit(frame));
+        return;
+    }
+
+    // Call the old version of the delegate method if it is implemented.
+    selector = @selector(webView:runJavaScriptAlertPanelWithMessage:);
+    if ([delegate respondsToSelector:selector]) {
+        CallUIDelegate(m_webView, selector, message);
+        return;
+    }
 }
 
 bool WebChromeClient::runJavaScriptConfirm(Frame* frame, const String& message)
 {
-    id wd = [m_webView UIDelegate];
-    // Check whether delegate implements new version, then whether delegate implements old version. If neither,
-    // fall back to shared delegate's implementation of new version.
-    if ([wd respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:)])
-        return [wd webView:m_webView runJavaScriptConfirmPanelWithMessage:message initiatedByFrame:kit(frame)];
-    if ([wd respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:)])
-        return [wd webView:m_webView runJavaScriptConfirmPanelWithMessage:message];    
-    return [[WebDefaultUIDelegate sharedUIDelegate] webView:m_webView runJavaScriptConfirmPanelWithMessage:message initiatedByFrame:kit(frame)];
+    id delegate = [m_webView UIDelegate];
+    SEL selector = @selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:);
+    if ([delegate respondsToSelector:selector])
+        return CallUIDelegateReturningBoolean(NO, m_webView, selector, message, kit(frame));
+
+    // Call the old version of the delegate method if it is implemented.
+    selector = @selector(webView:runJavaScriptConfirmPanelWithMessage:);
+    if ([delegate respondsToSelector:selector])
+        return CallUIDelegateReturningBoolean(NO, m_webView, selector, message);
+
+    return NO;
 }
 
 bool WebChromeClient::runJavaScriptPrompt(Frame* frame, const String& prompt, const String& defaultText, String& result)
 {
-    id wd = [m_webView UIDelegate];
-    // Check whether delegate implements new version, then whether delegate implements old version. If neither,
-    // fall back to shared delegate's implementation of new version.
-    if ([wd respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:)])
-        result = [wd webView:m_webView runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText initiatedByFrame:kit(frame)];
-    else if ([wd respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:)])
-        result = [wd webView:m_webView runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText];
-    else
-        result = [[WebDefaultUIDelegate sharedUIDelegate] webView:m_webView runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText initiatedByFrame:kit(frame)];
-    
+    id delegate = [m_webView UIDelegate];
+    SEL selector = @selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:);
+    if ([delegate respondsToSelector:selector]) {
+        result = (NSString *)CallUIDelegate(m_webView, selector, prompt, defaultText, kit(frame));
+        return !result.isNull();
+    }
+
+    // Call the old version of the delegate method if it is implemented.
+    selector = @selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:);
+    if ([delegate respondsToSelector:selector]) {
+        result = (NSString *)CallUIDelegate(m_webView, selector, prompt, defaultText);
+        return !result.isNull();
+    }
+
+    result = [[WebDefaultUIDelegate sharedUIDelegate] webView:m_webView runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText initiatedByFrame:kit(frame)];
     return !result.isNull();
 }
 
 bool WebChromeClient::shouldInterruptJavaScript()
 {
-    BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    id wd = [m_webView UIDelegate];
-    if ([wd respondsToSelector:@selector(webViewShouldInterruptJavaScript:)])
-        return [wd webViewShouldInterruptJavaScript:m_webView];
-    return false;
-    END_BLOCK_OBJC_EXCEPTIONS;
-    
-    return false;
+    return CallUIDelegate(m_webView, @selector(webViewShouldInterruptJavaScript:));
 }
 
 void WebChromeClient::setStatusbarText(const WebCore::String& status)
 {
-    id wd = [m_webView UIDelegate];
-
-    if ([wd respondsToSelector:@selector(webView:setStatusText:)]) {
-        // We want the temporaries allocated here to be released even before returning to the 
-        // event loop; see <http://bugs.webkit.org/show_bug.cgi?id=9880>.
-        NSAutoreleasePool* localPool = [[NSAutoreleasePool alloc] init];
-    
-        [wd webView:m_webView setStatusText:status];
-        
-        [localPool drain];
-    }
+    // We want the temporaries allocated here to be released even before returning to the 
+    // event loop; see <http://bugs.webkit.org/show_bug.cgi?id=9880>.
+    NSAutoreleasePool* localPool = [[NSAutoreleasePool alloc] init];
+    CallUIDelegate(m_webView, @selector(webView:setStatusText:), (NSString *)status);
+    [localPool drain];
 }
 
 bool WebChromeClient::tabsToLinks() const
@@ -386,9 +366,5 @@ void WebChromeClient::setToolTip(const String& toolTip)
 void WebChromeClient::print(Frame* frame)
 {
     WebFrameView* frameView = [kit(frame) frameView];
-    id wd = [m_webView UIDelegate];
-    if ([wd respondsToSelector:@selector(webView:printFrameView:)])
-        [wd webView:m_webView printFrameView:frameView];
-    else
-        [[WebDefaultUIDelegate sharedUIDelegate] webView:m_webView printFrameView:frameView];
+    CallUIDelegate(m_webView, @selector(webView:printFrameView:), frameView);
 }
index a63086a94a64d3e6b78e11aeda791b29a60b4bf9..892434831bb3ff963f5741099db0aaa2e81ad506 100644 (file)
@@ -249,7 +249,8 @@ static void fixMenusReceivedFromOldClients(NSMutableArray *newMenuItems, NSMutab
 NSMutableArray* WebContextMenuClient::getCustomMenuFromDefaultItems(ContextMenu* defaultMenu)
 {
     id delegate = [m_webView UIDelegate];
-    if (![delegate respondsToSelector:@selector(webView:contextMenuItemsForElement:defaultMenuItems:)])
+    SEL selector = @selector(webView:contextMenuItemsForElement:defaultMenuItems:);
+    if (![delegate respondsToSelector:selector])
         return defaultMenu->platformDescription();
 
     NSDictionary *element = [[[WebElementDictionary alloc] initWithHitTestResult:defaultMenu->hitTestResult()] autorelease];
@@ -264,25 +265,29 @@ NSMutableArray* WebContextMenuClient::getCustomMenuFromDefaultItems(ContextMenu*
     }
 
     NSMutableArray *defaultMenuItems = defaultMenu->platformDescription();
-    
+
     unsigned defaultItemsCount = [defaultMenuItems count];
     for (unsigned i = 0; i < defaultItemsCount; ++i)
         [[defaultMenuItems objectAtIndex:i] setRepresentedObject:element];
-            
+
     NSMutableArray *savedItems = [fixMenusToSendToOldClients(defaultMenuItems) retain];
-    NSMutableArray *newMenuItems = [[[delegate webView:m_webView contextMenuItemsForElement:element defaultMenuItems:defaultMenuItems] mutableCopy] autorelease];
+    NSArray *delegateSuppliedItems = CallUIDelegate(m_webView, selector, element, defaultMenuItems);
+    NSMutableArray *newMenuItems = [delegateSuppliedItems mutableCopy];
     fixMenusReceivedFromOldClients(newMenuItems, savedItems);
     [savedItems release];
-    return newMenuItems;
+    return [newMenuItems autorelease];
 }
 
 void WebContextMenuClient::contextMenuItemSelected(ContextMenuItem* item, const ContextMenu* parentMenu)
 {
     id delegate = [m_webView UIDelegate];
-    if ([delegate respondsToSelector:@selector(webView:contextMenuItemSelected:forElement:)]) {
+    SEL selector = @selector(webView:contextMenuItemSelected:forElement:);
+    if ([delegate respondsToSelector:selector]) {
         NSDictionary *element = [[WebElementDictionary alloc] initWithHitTestResult:parentMenu->hitTestResult()];
         NSMenuItem *platformItem = item->releasePlatformDescription();
-        [delegate webView:m_webView contextMenuItemSelected:platformItem forElement:element];
+
+        CallUIDelegate(m_webView, selector, platformItem, element);
+
         [element release];
         [platformItem release];
     }
index 1e3b2fb0446fb126a7c7d4b3acba0f09c8a37661..0dedbf14b11271ac1fa739b1671eba2c7c2c73c0 100644 (file)
@@ -32,6 +32,7 @@
 #import "WebFrameInternal.h"
 #import "WebHTMLViewInternal.h"
 #import "WebHTMLViewPrivate.h"
+#import "WebKitLogging.h"
 #import "WebNSPasteboardExtras.h"
 #import "WebNSURLExtras.h"
 #import "WebUIDelegate.h"
@@ -97,13 +98,21 @@ void WebDragClient::startDrag(DragImageRef dragImage, const IntPoint& at, const
     
     [topHTMLView _stopAutoscrollTimer];
     NSPasteboard *pasteboard = static_cast<ClipboardMac*>(clipboard)->pasteboard();
-    
-    // note per kwebster, the offset arg below is always ignored in positioning the image
-    id UIDelegate = [m_webView UIDelegate];
-    if ([UIDelegate respondsToSelector:@selector(webView:dragImage:at:offset:event:pasteboard:source:slideBack:forView:)])
-        [UIDelegate webView:m_webView dragImage:dragImage.get() at:(NSPoint)at offset:NSMakeSize(0, 0) event:event pasteboard:pasteboard source:htmlView.get() slideBack:YES forView:topHTMLView];
-    else
-        [topHTMLView dragImage:dragImage.get() at:(NSPoint)at offset:NSMakeSize(0, 0) event:event pasteboard:pasteboard source:htmlView.get() slideBack:YES];
+
+    NSSize offset = {0.0, 0.0};
+    id delegate = [m_webView UIDelegate];
+    SEL selector = @selector(webView:dragImage:at:offset:event:pasteboard:source:slideBack:forView:);
+    if ([delegate respondsToSelector:selector]) {
+        if ([m_webView _catchesDelegateExceptions]) {
+            @try {
+                [delegate webView:m_webView dragImage:dragImage.get() at:at offset:offset event:event pasteboard:pasteboard source:htmlView.get() slideBack:YES forView:topHTMLView];
+            } @catch (id exception) {
+                ReportDiscardedDelegateException(selector, exception);
+            }
+        } else
+            [delegate webView:m_webView dragImage:dragImage.get() at:at offset:offset event:event pasteboard:pasteboard source:htmlView.get() slideBack:YES forView:topHTMLView];
+    } else
+        [topHTMLView dragImage:dragImage.get() at:at offset:offset event:event pasteboard:pasteboard source:htmlView.get() slideBack:YES];
 }
 
 DragImageRef WebDragClient::createDragImageForLink(KURL& url, const String& title, Frame* frame)
index 68b8ab305f118ffeccfbe3c2900685da01f20dd7..bf8b3c4aca575713a186b6b091a8888f56b08893 100644 (file)
@@ -458,21 +458,21 @@ void WebEditorClient::textFieldDidBeginEditing(Element* element)
 {
     DOMHTMLInputElement* inputElement = [DOMHTMLInputElement _wrapHTMLInputElement:(HTMLInputElement*)element];
     FormDelegateLog(inputElement);
-    [[m_webView _formDelegate] textFieldDidBeginEditing:inputElement inFrame:kit(element->document()->frame())];
+    CallFormDelegate(m_webView, @selector(textFieldDidBeginEditing:inFrame:), inputElement, kit(element->document()->frame()));
 }
 
 void WebEditorClient::textFieldDidEndEditing(Element* element)
 {
     DOMHTMLInputElement* inputElement = [DOMHTMLInputElement _wrapHTMLInputElement:(HTMLInputElement*)element];
     FormDelegateLog(inputElement);
-    [[m_webView _formDelegate] textFieldDidEndEditing:inputElement inFrame:kit(element->document()->frame())];
+    CallFormDelegate(m_webView, @selector(textFieldDidEndEditing:inFrame:), inputElement, kit(element->document()->frame()));
 }
     
 void WebEditorClient::textDidChangeInTextField(Element* element)
 {
     DOMHTMLInputElement* inputElement = [DOMHTMLInputElement _wrapHTMLInputElement:(HTMLInputElement*)element];
     FormDelegateLog(inputElement);
-    [[m_webView _formDelegate] textDidChangeInTextField:(DOMHTMLInputElement *)inputElement inFrame:kit(element->document()->frame())];
+    CallFormDelegate(m_webView, @selector(textDidChangeInTextField:inFrame:), inputElement, kit(element->document()->frame()));
 }
 
 static SEL selectorForKeyEvent(KeyboardEvent* event)
@@ -500,32 +500,25 @@ static SEL selectorForKeyEvent(KeyboardEvent* event)
 bool WebEditorClient::doTextFieldCommandFromEvent(Element* element, KeyboardEvent* event)
 {
     DOMHTMLInputElement* inputElement = [DOMHTMLInputElement _wrapHTMLInputElement:(HTMLInputElement*)element];
-
-    bool result = false;
     FormDelegateLog(inputElement);
-
-    SEL selector = selectorForKeyEvent(event);
-    if (selector)
-        result = [[m_webView _formDelegate] textField:inputElement doCommandBySelector:selector inFrame:kit(element->document()->frame())];
-
-    return result;
+    if (SEL commandSelector = selectorForKeyEvent(event))
+        return CallFormDelegateReturningBoolean(NO, m_webView, @selector(textField:doCommandBySelector:inFrame:), inputElement, commandSelector, kit(element->document()->frame()));
+    return NO;
 }
 
 void WebEditorClient::textWillBeDeletedInTextField(Element* element)
 {
     DOMHTMLInputElement* inputElement = [DOMHTMLInputElement _wrapHTMLInputElement:(HTMLInputElement*)element];
-
-    // We're using the deleteBackward selector for all deletion operations since the autofill code treats all deletions the same way.
     FormDelegateLog(inputElement);
-    [[m_webView _formDelegate] textField:inputElement doCommandBySelector:@selector(deleteBackward:) inFrame:kit(element->document()->frame())];
+    // We're using the deleteBackward selector for all deletion operations since the autofill code treats all deletions the same way.
+    CallFormDelegateReturningBoolean(NO, m_webView, @selector(textField:doCommandBySelector:inFrame:), inputElement, @selector(deleteBackward:), kit(element->document()->frame()));
 }
 
 void WebEditorClient::textDidChangeInTextArea(Element* element)
 {
     DOMHTMLTextAreaElement* textAreaElement = [DOMHTMLTextAreaElement _wrapHTMLTextAreaElement:(HTMLTextAreaElement*)element];
-
     FormDelegateLog(textAreaElement);
-    [[m_webView _formDelegate] textDidChangeInTextArea:textAreaElement inFrame:kit(element->document()->frame())];
+    CallFormDelegate(m_webView, @selector(textDidChangeInTextArea:inFrame:), textAreaElement, kit(element->document()->frame()));
 }
 
 void WebEditorClient::ignoreWordInSpellDocument(const String& text)
index bd935f25a3a31a4cf99bc92efcea5e442987251e..ab631235420eadecc96db0f3615f90cac3270297 100644 (file)
@@ -293,21 +293,6 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
     return [[_frame frameView] window];
 }
 
-- (BOOL)runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText returningText:(NSString **)result
-{
-    WebView *wv = [self webView];
-    id wd = [wv UIDelegate];
-    // Check whether delegate implements new version, then whether delegate implements old version. If neither,
-    // fall back to shared delegate's implementation of new version.
-    if ([wd respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:)])
-        *result = [wd webView:wv runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText initiatedByFrame:_frame];
-    else if ([wd respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:)])
-        *result = [wd webView:wv runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText];
-    else
-        *result = [[WebDefaultUIDelegate sharedUIDelegate] webView:wv runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText initiatedByFrame:_frame];
-    return *result != nil;
-}
-
 - (void)runOpenPanelForFileButtonWithResultListener:(id<WebCoreOpenPanelResultListener>)resultListener
 {
     WebView *wv = [self webView];
@@ -446,20 +431,24 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
     NSView *view = nil;
     int errorCode = 0;
 
-    WebView *wv = [self webView];
-    id wd = [wv UIDelegate];
+    WebView *webView = [self webView];
+    SEL selector = @selector(webView:plugInViewWithArguments:);
 
-    if ([wd respondsToSelector:@selector(webView:plugInViewWithArguments:)]) {
+    if ([[webView UIDelegate] respondsToSelector:selector]) {
         NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
-        NSDictionary *arguments = [NSDictionary dictionaryWithObjectsAndKeys:
+        NSDictionary *arguments = [[NSDictionary alloc] initWithObjectsAndKeys:
             attributes, WebPlugInAttributesKey,
             [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
-            URL, WebPlugInBaseURLKey, // URL might be nil, so add it last
             [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
             element, WebPlugInContainingElementKey,
+            URL, WebPlugInBaseURLKey, // URL might be nil, so add it last
             nil];
+
+        view = CallUIDelegate(webView, selector, arguments);
+
         [attributes release];
-        view = [wd webView:wv plugInViewWithArguments:arguments];
+        [arguments release];
+
         if (view)
             return view;
     }
@@ -726,13 +715,10 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
 {
     WebView *webView = getWebView(_frame);
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidClearWindowObjectForFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.didClearWindowObjectForFrameFunc(frameLoadDelegate, @selector(webView:didClearWindowObject:forFrame:), webView, m_frame->windowScriptObject(), _frame);
-    } else if (implementations.delegateImplementsWindowScriptObjectAvailable) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.windowScriptObjectAvailableFunc(frameLoadDelegate, @selector(webView:windowScriptObjectAvailable:), webView, m_frame->windowScriptObject());
-    }
+    if (implementations.didClearWindowObjectForFrameFunc)
+        CallFrameLoadDelegate(implementations.didClearWindowObjectForFrameFunc, webView, @selector(webView:didClearWindowObject:forFrame:), m_frame->windowScriptObject(), _frame);
+    else if (implementations.windowScriptObjectAvailableFunc)
+        CallFrameLoadDelegate(implementations.windowScriptObjectAvailableFunc, webView, @selector(webView:windowScriptObjectAvailable:), m_frame->windowScriptObject());
 
     if ([webView scriptDebugDelegate] || [WebScriptDebugServer listenerCount]) {
         [_frame _detachScriptDebugger];
@@ -747,27 +733,20 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
 
 - (void)dashboardRegionsChanged:(NSMutableDictionary *)regions
 {
-    WebView *wv = [self webView];
-    id wd = [wv UIDelegate];
-    
-    [wv _addScrollerDashboardRegions:regions];
-    
+    WebView *webView = [self webView];
+    [webView _addScrollerDashboardRegions:regions];
+
     if (![self _compareDashboardRegions:regions]) {
-        if ([wd respondsToSelector:@selector(webView:dashboardRegionsChanged:)]) {
-            [wd webView:wv dashboardRegionsChanged:regions];
-            [lastDashboardRegions release];
-            lastDashboardRegions = [regions retain];
-        }
+        CallUIDelegate(webView, @selector(webView:dashboardRegionsChanged:), regions);
+
+        [lastDashboardRegions release];
+        lastDashboardRegions = [regions retain];
     }
 }
 
 - (void)willPopupMenu:(NSMenu *)menu
 {
-    WebView *wv = [self webView];
-    id wd = [wv UIDelegate];
-        
-    if ([wd respondsToSelector:@selector(webView:willPopupMenu:)])
-        [wd webView:wv willPopupMenu:menu];
+    CallUIDelegate([self webView], @selector(webView:willPopupMenu:), menu);
 }
 
 - (NSRect)customHighlightRect:(NSString*)type forLine:(NSRect)lineRect representedNode:(WebCore::Node *)node
index 7796e95847d26bc1540c2720e2ecd64c5ea25fae..83edbc1ba8666e24eb977128416a92aef2078988 100644 (file)
@@ -310,26 +310,23 @@ void WebFrameLoaderClient::setOriginalURLForDownload(WebDownload *download, cons
 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader* loader, const ResourceRequest& request, const ResourceResponse& response, int length)
 {
     WebView *webView = getWebView(m_webFrame.get());
-
-    id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
-    if (!implementations.delegateImplementsDidLoadResourceFromMemoryCache)
+    if (!implementations.didLoadResourceFromMemoryCacheFunc)
         return false;
 
-    implementations.didLoadResourceFromMemoryCacheFunc(resourceLoadDelegate, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:), webView, request.nsURLRequest(), response.nsURLResponse(), length, dataSource(loader));
+    CallResourceLoadDelegate(implementations.didLoadResourceFromMemoryCacheFunc, webView, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:), request.nsURLRequest(), response.nsURLResponse(), length, dataSource(loader));
     return true;
 }
 
 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
 {
     WebView *webView = getWebView(m_webFrame.get());
-    id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
 
-    id object;
+    id object = nil;
     BOOL shouldRelease = NO;
-    if (implementations.delegateImplementsIdentifierForRequest)
-        object = implementations.identifierForRequestFunc(resourceLoadDelegate, @selector(webView:identifierForInitialRequest:fromDataSource:), webView, request.nsURLRequest(), dataSource(loader));
+    if (implementations.identifierForRequestFunc)
+        object = CallResourceLoadDelegate(implementations.identifierForRequestFunc, webView, @selector(webView:identifierForInitialRequest:fromDataSource:), request.nsURLRequest(), dataSource(loader));
     else {
         object = [[NSObject alloc] init];
         shouldRelease = YES;
@@ -344,27 +341,25 @@ void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identi
 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
 {
     WebView *webView = getWebView(m_webFrame.get());
-    id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
 
     if (redirectResponse.isNull())
         static_cast<WebDocumentLoaderMac*>(loader)->increaseLoadCount(identifier);
 
-    if (implementations.delegateImplementsWillSendRequest)
-        request = implementations.willSendRequestFunc(resourceLoadDelegate, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:), webView, [webView _objectForIdentifier:identifier], request.nsURLRequest(), redirectResponse.nsURLResponse(), dataSource(loader));
+    if (implementations.willSendRequestFunc)
+        request = (NSURLRequest *)CallResourceLoadDelegate(implementations.willSendRequestFunc, webView, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:), [webView _objectForIdentifier:identifier], request.nsURLRequest(), redirectResponse.nsURLResponse(), dataSource(loader));
 }
 
 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
 {
     WebView *webView = getWebView(m_webFrame.get());
-    id resourceLoadDelegate = [webView resourceLoadDelegate];
     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
 
     NSURLAuthenticationChallenge *webChallenge = mac(challenge);
 
-    if (implementations.delegateImplementsDidReceiveAuthenticationChallenge) {
+    if (implementations.didReceiveAuthenticationChallengeFunc) {
         if (id resource = [webView _objectForIdentifier:identifier]) {
-            [resourceLoadDelegate webView:webView resource:resource didReceiveAuthenticationChallenge:webChallenge fromDataSource:dataSource(loader)];
+            CallResourceLoadDelegate(implementations.didReceiveAuthenticationChallengeFunc, webView, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:), resource, webChallenge, dataSource(loader));
             return;
         }
     }
@@ -376,14 +371,12 @@ void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoa
 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge&challenge)
 {
     WebView *webView = getWebView(m_webFrame.get());
-    id resourceLoadDelegate = [webView resourceLoadDelegate];
     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
-
     NSURLAuthenticationChallenge *webChallenge = mac(challenge);
 
-    if (implementations.delegateImplementsDidCancelAuthenticationChallenge) {
+    if (implementations.didCancelAuthenticationChallengeFunc) {
         if (id resource = [webView _objectForIdentifier:identifier]) {
-            [resourceLoadDelegate webView:webView resource:resource didCancelAuthenticationChallenge:webChallenge fromDataSource:dataSource(loader)];
+            CallResourceLoadDelegate(implementations.didCancelAuthenticationChallengeFunc, webView, @selector(webView:resource:didCancelAuthenticationChallenge:fromDataSource:), resource, webChallenge, dataSource(loader));
             return;
         }
     }
@@ -394,23 +387,21 @@ void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoad
 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
 {
     WebView *webView = getWebView(m_webFrame.get());
-    id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
-
-    if (implementations.delegateImplementsDidReceiveResponse) {
+    if (implementations.didReceiveResponseFunc) {
         if (id resource = [webView _objectForIdentifier:identifier])
-            implementations.didReceiveResponseFunc(resourceLoadDelegate, @selector(webView:resource:didReceiveResponse:fromDataSource:), webView, resource, response.nsURLResponse(), dataSource(loader));
+            CallResourceLoadDelegate(implementations.didReceiveResponseFunc, webView, @selector(webView:resource:didReceiveResponse:fromDataSource:), resource, response.nsURLResponse(), dataSource(loader));
     }
 }
 
 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader* loader, unsigned long identifier, NSCachedURLResponse* response) const
 {
     WebView *webView = getWebView(m_webFrame.get());
-    id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsWillCacheResponse) {
-        if (id resource = [webView _objectForIdentifier:identifier]) 
-            return implementations.willCacheResponseFunc(resourceLoadDelegate, @selector(webView:resource:willCacheResponse:fromDataSource:), webView, resource, response, dataSource(loader));
+
+    if (implementations.willCacheResponseFunc) {
+        if (id resource = [webView _objectForIdentifier:identifier])
+            return CallResourceLoadDelegate(implementations.willCacheResponseFunc, webView, @selector(webView:resource:willCacheResponse:fromDataSource:), resource, response, dataSource(loader));
     }
 
     return response;
@@ -419,25 +410,23 @@ NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader* loa
 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int lengthReceived)
 {
     WebView *webView = getWebView(m_webFrame.get());
-    id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
-
-    if (implementations.delegateImplementsDidReceiveContentLength) {
-        if (id resource = [webView _objectForIdentifier:identifier]) 
-            implementations.didReceiveContentLengthFunc(resourceLoadDelegate, @selector(webView:resource:didReceiveContentLength:fromDataSource:), webView, resource, (NSUInteger)lengthReceived, dataSource(loader));
+    if (implementations.didReceiveContentLengthFunc) {
+        if (id resource = [webView _objectForIdentifier:identifier])
+            CallResourceLoadDelegate(implementations.didReceiveContentLengthFunc, webView, @selector(webView:resource:didReceiveContentLength:fromDataSource:), resource, (NSInteger)lengthReceived, dataSource(loader));
     }
 }
 
 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
 {
     WebView *webView = getWebView(m_webFrame.get());
-    id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
 
-    if (implementations.delegateImplementsDidFinishLoadingFromDataSource) {
+    if (implementations.didFinishLoadingFromDataSourceFunc) {
         if (id resource = [webView _objectForIdentifier:identifier])
-            implementations.didFinishLoadingFromDataSourceFunc(resourceLoadDelegate, @selector(webView:resource:didFinishLoadingFromDataSource:), webView, resource, dataSource(loader));
+            CallResourceLoadDelegate(implementations.didFinishLoadingFromDataSourceFunc, webView, @selector(webView:resource:didFinishLoadingFromDataSource:), resource, dataSource(loader));
     }
+
     [webView _removeObjectForIdentifier:identifier];
 
     static_cast<WebDocumentLoaderMac*>(loader)->decreaseLoadCount(identifier);
@@ -446,13 +435,13 @@ void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsi
 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
 {
     WebView *webView = getWebView(m_webFrame.get());
-    id resourceLoadDelegate = WebViewGetResourceLoadDelegate(webView);
     WebResourceDelegateImplementationCache implementations = WebViewGetResourceLoadDelegateImplementations(webView);
 
-    if (implementations.delegateImplementsDidFailLoadingWithErrorFromDataSource) {
+    if (implementations.didFailLoadingWithErrorFromDataSourceFunc) {
         if (id resource = [webView _objectForIdentifier:identifier])
-            implementations.didFailLoadingWithErrorFromDataSourceFunc(resourceLoadDelegate, @selector(webView:resource:didFailLoadingWithError:fromDataSource:), webView, resource, error, dataSource(loader));
+            CallResourceLoadDelegate(implementations.didFailLoadingWithErrorFromDataSourceFunc, webView, @selector(webView:resource:didFailLoadingWithError:fromDataSource:), resource, (NSError *)error, dataSource(loader));
     }
+
     [webView _removeObjectForIdentifier:identifier];
 
     static_cast<WebDocumentLoaderMac*>(loader)->decreaseLoadCount(identifier);
@@ -462,60 +451,48 @@ void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
 {
     WebView *webView = getWebView(m_webFrame.get());
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidHandleOnloadEventsForFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.didHandleOnloadEventsForFrameFunc(frameLoadDelegate, @selector(webView:didHandleOnloadEventsForFrame:), webView, m_webFrame.get());
-    }
+    if (implementations.didHandleOnloadEventsForFrameFunc)
+        CallFrameLoadDelegate(implementations.didHandleOnloadEventsForFrameFunc, webView, @selector(webView:didHandleOnloadEventsForFrame:), m_webFrame.get());
 }
 
 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
 {
     WebView *webView = getWebView(m_webFrame.get());
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidReceiveServerRedirectForProvisionalLoadForFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.didReceiveServerRedirectForProvisionalLoadForFrameFunc(frameLoadDelegate, @selector(webView:didReceiveServerRedirectForProvisionalLoadForFrame:), webView, m_webFrame.get());
-    }
+    if (implementations.didReceiveServerRedirectForProvisionalLoadForFrameFunc)
+        CallFrameLoadDelegate(implementations.didReceiveServerRedirectForProvisionalLoadForFrameFunc, webView, @selector(webView:didHandleOnloadEventsForFrame:), m_webFrame.get());
 }
 
 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
 {
     WebView *webView = getWebView(m_webFrame.get());
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidCancelClientRedirectForFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.didCancelClientRedirectForFrameFunc(frameLoadDelegate, @selector(webView:didCancelClientRedirectForFrame:), webView, m_webFrame.get());
-    }
+    if (implementations.didCancelClientRedirectForFrameFunc)
+        CallFrameLoadDelegate(implementations.didCancelClientRedirectForFrameFunc, webView, @selector(webView:didCancelClientRedirectForFrame:), m_webFrame.get());
 }
 
 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& URL, double delay, double fireDate)
 {
     WebView *webView = getWebView(m_webFrame.get());
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsWillPerformClientRedirectToURLDelayFireDateForFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.willPerformClientRedirectToURLDelayFireDateForFrameFunc(frameLoadDelegate, @selector(webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:), webView, URL.getNSURL(), delay, [NSDate dateWithTimeIntervalSince1970:fireDate], m_webFrame.get());
-    }
+    if (implementations.willPerformClientRedirectToURLDelayFireDateForFrameFunc)
+        CallFrameLoadDelegate(implementations.willPerformClientRedirectToURLDelayFireDateForFrameFunc, webView, @selector(webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:), URL.getNSURL(), delay, [NSDate dateWithTimeIntervalSince1970:fireDate], m_webFrame.get());
 }
 
 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
 {
     WebView *webView = getWebView(m_webFrame.get());
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidChangeLocationWithinPageForFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.didChangeLocationWithinPageForFrameFunc(frameLoadDelegate, @selector(webView:didChangeLocationWithinPageForFrame:), webView, m_webFrame.get());
-    }
+    if (implementations.didChangeLocationWithinPageForFrameFunc)
+        CallFrameLoadDelegate(implementations.didChangeLocationWithinPageForFrameFunc, webView, @selector(webView:didChangeLocationWithinPageForFrame:), m_webFrame.get());
 }
 
 void WebFrameLoaderClient::dispatchWillClose()
 {
     WebView *webView = getWebView(m_webFrame.get());   
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsWillCloseFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.willCloseFrameFunc(frameLoadDelegate, @selector(webView:willCloseFrame:), webView, m_webFrame.get());
-    }
+    if (implementations.willCloseFrameFunc)
+        CallFrameLoadDelegate(implementations.willCloseFrameFunc, webView, @selector(webView:willCloseFrame:), m_webFrame.get());
 }
 
 void WebFrameLoaderClient::dispatchDidReceiveIcon()
@@ -527,12 +504,10 @@ void WebFrameLoaderClient::dispatchDidReceiveIcon()
     [webView _willChangeValueForKey:_WebMainFrameIconKey];
 
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidReceiveIconForFrame) {
+    if (implementations.didReceiveIconForFrameFunc) {
         Image* image = iconDatabase()->iconForPageURL(core(m_webFrame.get())->loader()->url().url(), IntSize(16, 16));
-        if (NSImage *icon = webGetNSImage(image, NSMakeSize(16, 16))) {
-            id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-            implementations.didReceiveIconForFrameFunc(frameLoadDelegate, @selector(webView:didReceiveIcon:forFrame:), webView, icon, m_webFrame.get());
-        }
+        if (NSImage *icon = webGetNSImage(image, NSMakeSize(16, 16)))
+            CallFrameLoadDelegate(implementations.didReceiveIconForFrameFunc, webView, @selector(webView:didReceiveIcon:forFrame:), icon, m_webFrame.get());
     }
 
     [webView _didChangeValueForKey:_WebMainFrameIconKey];
@@ -544,20 +519,16 @@ void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
     [webView _didStartProvisionalLoadForFrame:m_webFrame.get()];
 
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidStartProvisionalLoadForFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.didStartProvisionalLoadForFrameFunc(frameLoadDelegate, @selector(webView:didStartProvisionalLoadForFrame:), webView, m_webFrame.get());
-    }
+    if (implementations.didStartProvisionalLoadForFrameFunc)
+        CallFrameLoadDelegate(implementations.didStartProvisionalLoadForFrameFunc, webView, @selector(webView:didStartProvisionalLoadForFrame:), m_webFrame.get());
 }
 
 void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title)
 {
     WebView *webView = getWebView(m_webFrame.get());   
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidReceiveTitleForFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.didReceiveTitleForFrameFunc(frameLoadDelegate, @selector(webView:didReceiveTitle:forFrame:), webView, title, m_webFrame.get());
-    }
+    if (implementations.didReceiveTitleForFrameFunc)
+        CallFrameLoadDelegate(implementations.didReceiveTitleForFrameFunc, webView, @selector(webView:didReceiveTitle:forFrame:), (NSString *)title, m_webFrame.get());
 }
 
 void WebFrameLoaderClient::dispatchDidCommitLoad()
@@ -569,21 +540,19 @@ void WebFrameLoaderClient::dispatchDidCommitLoad()
     [webView _didCommitLoadForFrame:m_webFrame.get()];
 
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidCommitLoadForFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.didCommitLoadForFrameFunc(frameLoadDelegate, @selector(webView:didCommitLoadForFrame:), webView, m_webFrame.get());
-    }
+    if (implementations.didCommitLoadForFrameFunc)
+        CallFrameLoadDelegate(implementations.didCommitLoadForFrameFunc, webView, @selector(webView:didCommitLoadForFrame:), m_webFrame.get());
 }
 
 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
 {
     WebView *webView = getWebView(m_webFrame.get());   
     [webView _didFailProvisionalLoadWithError:error forFrame:m_webFrame.get()];
+
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidFailProvisionalLoadWithErrorForFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.didFailProvisionalLoadWithErrorForFrameFunc(frameLoadDelegate, @selector(webView:didFailProvisionalLoadWithError:forFrame:), webView, error, m_webFrame.get());
-    }
+    if (implementations.didFailProvisionalLoadWithErrorForFrameFunc)
+        CallFrameLoadDelegate(implementations.didFailProvisionalLoadWithErrorForFrameFunc, webView, @selector(webView:didFailProvisionalLoadWithError:forFrame:), (NSError *)error, m_webFrame.get());
+
     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
 }
 
@@ -593,10 +562,8 @@ void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
     [webView _didFailLoadWithError:error forFrame:m_webFrame.get()];
 
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidFailLoadWithErrorForFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.didFailLoadWithErrorForFrameFunc(frameLoadDelegate, @selector(webView:didFailLoadWithError:forFrame:), webView, error, m_webFrame.get());
-    }
+    if (implementations.didFailLoadWithErrorForFrameFunc)
+        CallFrameLoadDelegate(implementations.didFailLoadWithErrorForFrameFunc, webView, @selector(webView:didFailLoadWithError:forFrame:), (NSError *)error, m_webFrame.get());
 
     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
 }
@@ -605,10 +572,8 @@ void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
 {
     WebView *webView = getWebView(m_webFrame.get());
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidFinishDocumentLoadForFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.didFinishDocumentLoadForFrameFunc(frameLoadDelegate, @selector(webView:didFinishDocumentLoadForFrame:), webView, m_webFrame.get());
-    }
+    if (implementations.didFinishDocumentLoadForFrameFunc)
+        CallFrameLoadDelegate(implementations.didFinishDocumentLoadForFrameFunc, webView, @selector(webView:didFinishDocumentLoadForFrame:), m_webFrame.get());
 }
 
 void WebFrameLoaderClient::dispatchDidFinishLoad()
@@ -617,10 +582,8 @@ void WebFrameLoaderClient::dispatchDidFinishLoad()
     [webView _didFinishLoadForFrame:m_webFrame.get()];
 
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidFinishLoadForFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.didFinishLoadForFrameFunc(frameLoadDelegate, @selector(webView:didFinishLoadForFrame:), webView, m_webFrame.get());
-    }
+    if (implementations.didFinishLoadForFrameFunc)
+        CallFrameLoadDelegate(implementations.didFinishLoadForFrameFunc, webView, @selector(webView:didFinishLoadForFrame:), m_webFrame.get());
 
     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];
 }
@@ -629,19 +592,15 @@ void WebFrameLoaderClient::dispatchDidFirstLayout()
 {
     WebView *webView = getWebView(m_webFrame.get());
     WebFrameLoadDelegateImplementationCache implementations = WebViewGetFrameLoadDelegateImplementations(webView);
-    if (implementations.delegateImplementsDidFirstLayoutInFrame) {
-        id frameLoadDelegate = WebViewGetFrameLoadDelegate(webView);
-        implementations.didFirstLayoutInFrameFunc(frameLoadDelegate, @selector(webView:didFirstLayoutInFrame:), webView, m_webFrame.get());
-    }
+    if (implementations.didFirstLayoutInFrameFunc)
+        CallFrameLoadDelegate(implementations.didFirstLayoutInFrameFunc, webView, @selector(webView:didFirstLayoutInFrame:), m_webFrame.get());
 }
 
 Frame* WebFrameLoaderClient::dispatchCreatePage()
 {
     WebView *currentWebView = getWebView(m_webFrame.get());
-    id wd = [currentWebView UIDelegate];
-    if ([wd respondsToSelector:@selector(webView:createWebViewWithRequest:)])
-        return core([[wd webView:currentWebView createWebViewWithRequest:nil] mainFrame]);
-    return 0;
+    WebView *newWebView = CallUIDelegate(currentWebView, @selector(webView:createWebViewWithRequest:), nil);
+    return core([newWebView mainFrame]);
 }
 
 void WebFrameLoaderClient::dispatchShow()
@@ -694,8 +653,7 @@ void WebFrameLoaderClient::cancelPolicyCheck()
 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
 {
     WebView *webView = getWebView(m_webFrame.get());
-    [[webView _policyDelegateForwarder] webView:webView
-        unableToImplementPolicyWithError:error frame:m_webFrame.get()];    
+    [[webView _policyDelegateForwarder] webView:webView unableToImplementPolicyWithError:error frame:m_webFrame.get()];    
 }
 
 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
@@ -711,11 +669,7 @@ void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function,
     for (HashMap<String, String>::const_iterator it = formState->values().begin(); it != end; ++it)
         [dictionary setObject:it->second forKey:it->first];
 
-    [formDelegate frame:m_webFrame.get()
-            sourceFrame:kit(formState->sourceFrame())
-         willSubmitForm:kit(formState->form())
-             withValues:dictionary
-     submissionListener:setUpPolicyListener(function).get()];
+    CallFormDelegate(getWebView(m_webFrame.get()), @selector(frame:sourceFrame:willSubmitForm:withValues:submissionListener:), m_webFrame.get(), kit(formState->sourceFrame()), kit(formState->form()), dictionary, setUpPolicyListener(function).get());
 
     [dictionary release];
 }
@@ -723,8 +677,7 @@ void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function,
 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader* loader)
 {
     if ([WebScriptDebugServer listenerCount])
-        [[WebScriptDebugServer sharedScriptDebugServer] webView:getWebView(m_webFrame.get())
-            didLoadMainResourceForDataSource:dataSource(loader)];
+        [[WebScriptDebugServer sharedScriptDebugServer] webView:getWebView(m_webFrame.get()) didLoadMainResourceForDataSource:dataSource(loader)];
 }
 
 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader* loader)
index cbc05f78998d3f5389fdf31c8cb81638f1a553f0..535d85e20581d923986ff296bbd5feed6394cbcf 100644 (file)
@@ -2058,13 +2058,8 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
     _private->selectorForDoCommandBySelector = 0;
     if (callerAlreadyCalledDelegate)
         return NO;
-
     WebView *webView = [self _webView];
-    id editingDelegate = [webView editingDelegate];
-    if (![editingDelegate respondsToSelector:@selector(webView:doCommandBySelector:)])
-        return NO;
-
-    return [editingDelegate webView:webView doCommandBySelector:selector];
+    return [[webView _editingDelegateForwarder] webView:webView doCommandBySelector:selector];
 }
 
 - (void)callWebCoreCommand:(SEL)selector
@@ -2450,12 +2445,7 @@ WEBCORE_COMMAND(moveWordRightAndModifySelection)
 - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item
 {
     BOOL result = [self validateUserInterfaceItemWithoutDelegate:item];
-
-    id ud = [[self _webView] UIDelegate];
-    if (ud && [ud respondsToSelector:@selector(webView:validateUserInterfaceItem:defaultValidation:)])
-        return [ud webView:[self _webView] validateUserInterfaceItem:item defaultValidation:result];
-
-    return result;
+    return CallUIDelegateReturningBoolean(result, [self _webView], @selector(webView:validateUserInterfaceItem:defaultValidation:), item, result);
 }
 
 - (BOOL)acceptsFirstResponder
index 9c7cb93a7b708b666294c0a5f2bc9f225f72f1f2..ccc17967f4ac9794340e83baf3e0603391e5730c 100644 (file)
@@ -493,12 +493,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
 - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item
 {
     BOOL result = [self validateUserInterfaceItemWithoutDelegate:item];
-
-    id ud = [[self _webView] UIDelegate];
-    if (ud && [ud respondsToSelector:@selector(webView:validateUserInterfaceItem:defaultValidation:)])
-        return [ud webView:[self _webView] validateUserInterfaceItem:item defaultValidation:result];
-
-    return result;
+    return CallUIDelegateReturningBoolean(result, [self _webView], @selector(webView:validateUserInterfaceItem:defaultValidation:), item, result);
 }
 
 #pragma mark INTERFACE BUILDER ACTIONS FOR SAFARI
@@ -982,10 +977,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
 
     // Delegate method sent when the user requests downloading the PDF file to disk. We pass NO for
     // showingPanel: so that the PDF file is saved to the standard location without user intervention.
-    id UIDelegate = [[self _webView] UIDelegate];
-
-    if (UIDelegate && [UIDelegate respondsToSelector:@selector(webView:saveFrameView:showingPanel:)])
-        [UIDelegate webView:[self _webView] saveFrameView:[[dataSource webFrame] frameView] showingPanel:NO];
+    CallUIDelegate([self _webView], @selector(webView:saveFrameView:showingPanel:), [[dataSource webFrame] frameView], NO);
 }
 
 @end
index de027fbcf0f8ffe0f0014f5648dbb803ede2f664..7c159a3ecece2a2f9387a1371f5da1d75b974937 100644 (file)
@@ -259,6 +259,15 @@ static int pluginDatabaseClientCount = 0;
 - (BOOL)validateUserInterfaceItemWithoutDelegate:(id <NSValidatedUserInterfaceItem>)item;
 @end
 
+@interface _WebSafeForwarder : NSObject
+{
+    id target; // Non-retained. Don't retain delegates.
+    id defaultTarget;
+    BOOL catchExceptions;
+}
+- (id)initWithTarget:(id)target defaultTarget:(id)defaultTarget catchExceptions:(BOOL)catchExceptions;
+@end
+
 @interface WebViewPrivate : NSObject
 {
 @public
@@ -289,7 +298,7 @@ static int pluginDatabaseClientCount = 0;
     WebPreferences *preferences;
     BOOL useSiteSpecificSpoofing;
         
-    BOOL lastElementWasNonNil;
+    BOOL lastElementWasNil;
 
     NSWindow *hostWindow;
 
@@ -310,6 +319,7 @@ static int pluginDatabaseClientCount = 0;
     BOOL becomingFirstResponderFromOutside;
     BOOL hoverFeedbackSuspended;
     BOOL usesPageCache;
+    BOOL catchesDelegateExceptions;
 
     NSColor *backgroundColor;
 
@@ -345,6 +355,9 @@ static int pluginDatabaseClientCount = 0;
 - (void)_notifyTextSizeMultiplierChanged;
 @end
 
+@interface WebView (WebCallDelegateFunctions)
+@end
+
 NSString *WebElementDOMNodeKey =            @"WebElementDOMNode";
 NSString *WebElementFrameKey =              @"WebElementFrame";
 NSString *WebElementImageKey =              @"WebElementImage";
@@ -751,16 +764,11 @@ static bool debugWidget = true;
 
 - (WebView *)_openNewWindowWithRequest:(NSURLRequest *)request
 {
-    id wd = [self UIDelegate];
-    WebView *newWindowWebView = nil;
-    if ([wd respondsToSelector:@selector(webView:createWebViewWithRequest:)])
-        newWindowWebView = [wd webView:self createWebViewWithRequest:request];
-    else {
-        newWindowWebView = [[WebDefaultUIDelegate sharedUIDelegate] webView:self createWebViewWithRequest: request];
-    }
-
-    [[newWindowWebView _UIDelegateForwarder] webViewShow: newWindowWebView];
+    WebView *newWindowWebView = CallUIDelegate(self, @selector(webView:createWebViewWithRequest:), request);
+    if (!newWindowWebView)
+        return nil;
 
+    CallUIDelegate(newWindowWebView, @selector(webViewShow:));
     return newWindowWebView;
 }
 
@@ -771,24 +779,21 @@ static bool debugWidget = true;
 
 - (NSMenu *)_menuForElement:(NSDictionary *)element defaultItems:(NSArray *)items
 {
-    NSArray *defaultMenuItems = [[WebDefaultUIDelegate sharedUIDelegate]
-          webView:self contextMenuItemsForElement:element defaultMenuItems:items];
-    NSArray *menuItems = defaultMenuItems;
-    NSMenu *menu = nil;
-    unsigned i;
+    NSArray *defaultMenuItems = [[WebDefaultUIDelegate sharedUIDelegate] webView:self contextMenuItemsForElement:element defaultMenuItems:items];
 
-    if ([_private->UIDelegate respondsToSelector:@selector(webView:contextMenuItemsForElement:defaultMenuItems:)])
-        menuItems = [_private->UIDelegate webView:self contextMenuItemsForElement:element defaultMenuItems:defaultMenuItems];
+    NSArray *menuItems = CallUIDelegate(self, @selector(webView:contextMenuItemsForElement:defaultMenuItems:), element, defaultMenuItems);
+    if (!menuItems)
+        return nil;
 
-    if (menuItems && [menuItems count] > 0) {
-        menu = [[[NSMenu alloc] init] autorelease];
+    unsigned count = [menuItems count];
+    if (!count)
+        return nil;
 
-        for (i=0; i<[menuItems count]; i++) {
-            [menu addItem:[menuItems objectAtIndex:i]];
-        }
-    }
+    NSMenu *menu = [[NSMenu alloc] init];
+    for (unsigned i = 0; i < count; i++)
+        [menu addItem:[menuItems objectAtIndex:i]];
 
-    return menu;
+    return [menu autorelease];
 }
 
 - (void)_mouseDidMoveOverElement:(NSDictionary *)dictionary modifierFlags:(NSUInteger)modifierFlags
@@ -796,14 +801,13 @@ static bool debugWidget = true;
     // When the mouse isn't over this view at all, we'll get called with a dictionary of nil over
     // and over again. So it's a good idea to catch that here and not send multiple calls to the delegate
     // for that case.
-    
-    if (dictionary && _private->lastElementWasNonNil) {
-        [[self _UIDelegateForwarder] webView:self mouseDidMoveOverElement:dictionary modifierFlags:modifierFlags];
-    }
-    _private->lastElementWasNonNil = dictionary != nil;
-}
+    if (!dictionary && _private->lastElementWasNil)
+        return;
 
+    _private->lastElementWasNil = !dictionary;
 
+    CallUIDelegate(self, @selector(webView:mouseDidMoveOverElement:modifierFlags:), dictionary, modifierFlags);
+}
 
 - (void)_loadBackForwardListFromOtherView:(WebView *)otherView
 {
@@ -933,52 +937,39 @@ static bool debugWidget = true;
 - (void)_cacheResourceLoadDelegateImplementations
 {
     WebResourceDelegateImplementationCache *cache = &_private->resourceLoadDelegateImplementations;
-    id delegate = [self resourceLoadDelegate];
+    id delegate = _private->resourceProgressDelegate;
     Class delegateClass = [delegate class];
 
-    cache->delegateImplementsDidCancelAuthenticationChallenge = [delegate respondsToSelector:@selector(webView:resource:didCancelAuthenticationChallenge:fromDataSource:)];
-    cache->delegateImplementsDidReceiveAuthenticationChallenge = [delegate respondsToSelector:@selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:)];
-    cache->delegateImplementsDidFinishLoadingFromDataSource = [delegate respondsToSelector:@selector(webView:resource:didFinishLoadingFromDataSource:)];
-    cache->delegateImplementsDidFailLoadingWithErrorFromDataSource = [delegate respondsToSelector:@selector(webView:resource:didFailLoadingWithError:fromDataSource:)];
-    cache->delegateImplementsDidReceiveContentLength = [delegate respondsToSelector:@selector(webView:resource:didReceiveContentLength:fromDataSource:)];
-    cache->delegateImplementsDidReceiveResponse = [delegate respondsToSelector:@selector(webView:resource:didReceiveResponse:fromDataSource:)];
-    cache->delegateImplementsWillSendRequest = [delegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)];
-    cache->delegateImplementsIdentifierForRequest = [delegate respondsToSelector:@selector(webView:identifierForInitialRequest:fromDataSource:)];
-    cache->delegateImplementsDidLoadResourceFromMemoryCache = [delegate respondsToSelector:@selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:)];
-    cache->delegateImplementsWillCacheResponse = [delegate respondsToSelector:@selector(webView:resource:willCacheResponse:fromDataSource:)];
-
 #if defined(OBJC_API_VERSION) && OBJC_API_VERSION > 0
 #define GET_OBJC_METHOD_IMP(class,selector) class_getMethodImplementation(class, selector)
 #else
 #define GET_OBJC_METHOD_IMP(class,selector) class_getInstanceMethod(class, selector)->method_imp
 #endif
 
-    if (cache->delegateImplementsDidCancelAuthenticationChallenge)
-        cache->didCancelAuthenticationChallengeFunc = (WebDidCancelAuthenticationChallengeFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:));
-    if (cache->delegateImplementsDidReceiveAuthenticationChallenge)
-        cache->didReceiveAuthenticationChallengeFunc = (WebDidReceiveAuthenticationChallengeFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:));
-    if (cache->delegateImplementsDidFinishLoadingFromDataSource)
-        cache->didFinishLoadingFromDataSourceFunc = (WebDidFinishLoadingFromDataSourceFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didFinishLoadingFromDataSource:));
-    if (cache->delegateImplementsDidFailLoadingWithErrorFromDataSource)
-        cache->didFailLoadingWithErrorFromDataSourceFunc = (WebDidFailLoadingWithErrorFromDataSourceFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didFailLoadingWithError:fromDataSource:));
-    if (cache->delegateImplementsDidReceiveContentLength)
-        cache->didReceiveContentLengthFunc = (WebDidReceiveContentLengthFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didReceiveContentLength:fromDataSource:));
-    if (cache->delegateImplementsDidReceiveResponse)
-        cache->didReceiveResponseFunc = (WebDidReceiveResponseFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didReceiveResponse:fromDataSource:));
-    if (cache->delegateImplementsWillSendRequest)
-        cache->willSendRequestFunc = (WebWillSendRequestFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:));
-    if (cache->delegateImplementsIdentifierForRequest)
-        cache->identifierForRequestFunc = (WebIdentifierForRequestFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:identifierForInitialRequest:fromDataSource:));
-    if (cache->delegateImplementsDidLoadResourceFromMemoryCache)
-        cache->didLoadResourceFromMemoryCacheFunc = (WebDidLoadResourceFromMemoryCacheFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:));
-    if (cache->delegateImplementsWillCacheResponse)
-        cache->willCacheResponseFunc = (WebWillCacheResponseFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:willCacheResponse:fromDataSource:));
-#undef GET_OBJC_METHOD_IMP
-}
+    if ([delegate respondsToSelector:@selector(webView:resource:didCancelAuthenticationChallenge:fromDataSource:)])
+        cache->didCancelAuthenticationChallengeFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:));
+    if ([delegate respondsToSelector:@selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:)])
+        cache->didReceiveAuthenticationChallengeFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:));
+    if ([delegate respondsToSelector:@selector(webView:resource:didFinishLoadingFromDataSource:)])
+        cache->didFinishLoadingFromDataSourceFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didFinishLoadingFromDataSource:));
+    if ([delegate respondsToSelector:@selector(webView:resource:didFailLoadingWithError:fromDataSource:)])
+        cache->didFailLoadingWithErrorFromDataSourceFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didFailLoadingWithError:fromDataSource:));
+    if ([delegate respondsToSelector:@selector(webView:resource:didReceiveContentLength:fromDataSource:)])
+        cache->didReceiveContentLengthFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didReceiveContentLength:fromDataSource:));
+    if ([delegate respondsToSelector:@selector(webView:resource:didReceiveResponse:fromDataSource:)])
+        cache->didReceiveResponseFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:didReceiveResponse:fromDataSource:));
+    if ([delegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)])
+        cache->willSendRequestFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:));
+    if ([delegate respondsToSelector:@selector(webView:identifierForInitialRequest:fromDataSource:)])
+        cache->identifierForRequestFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:identifierForInitialRequest:fromDataSource:));
+    if ([delegate respondsToSelector:@selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:)])
+        cache->didLoadResourceFromMemoryCacheFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:));
+    if ([delegate respondsToSelector:@selector(webView:resource:willCacheResponse:fromDataSource:)])
+        cache->willCacheResponseFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:resource:willCacheResponse:fromDataSource:));
+    if ([delegate respondsToSelector:@selector(webView:plugInFailedWithError:dataSource:)])
+        cache->plugInFailedWithErrorFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:plugInFailedWithError:dataSource:));
 
-id WebViewGetResourceLoadDelegate(WebView *webView)
-{
-    return webView->_private->resourceProgressDelegate;
+#undef GET_OBJC_METHOD_IMP
 }
 
 WebResourceDelegateImplementationCache WebViewGetResourceLoadDelegateImplementations(WebView *webView)
@@ -989,73 +980,51 @@ WebResourceDelegateImplementationCache WebViewGetResourceLoadDelegateImplementat
 - (void)_cacheFrameLoadDelegateImplementations
 {
     WebFrameLoadDelegateImplementationCache *cache = &_private->frameLoadDelegateImplementations;
-    id delegate = [self frameLoadDelegate];
+    id delegate = _private->frameLoadDelegate;
     Class delegateClass = [delegate class];
 
-    cache->delegateImplementsDidClearWindowObjectForFrame = [delegate respondsToSelector:@selector(webView:didClearWindowObject:forFrame:)];
-    cache->delegateImplementsWindowScriptObjectAvailable = [delegate respondsToSelector:@selector(webView:windowScriptObjectAvailable:)];
-    cache->delegateImplementsDidHandleOnloadEventsForFrame = [delegate respondsToSelector:@selector(webView:didHandleOnloadEventsForFrame:)];
-    cache->delegateImplementsDidReceiveServerRedirectForProvisionalLoadForFrame = [delegate respondsToSelector:@selector(webView:didReceiveServerRedirectForProvisionalLoadForFrame:)];
-    cache->delegateImplementsDidCancelClientRedirectForFrame = [delegate respondsToSelector:@selector(webView:didCancelClientRedirectForFrame:)];
-    cache->delegateImplementsWillPerformClientRedirectToURLDelayFireDateForFrame = [delegate respondsToSelector:@selector(webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:)];
-    cache->delegateImplementsDidChangeLocationWithinPageForFrame = [delegate respondsToSelector:@selector(webView:didChangeLocationWithinPageForFrame:)];
-    cache->delegateImplementsWillCloseFrame = [delegate respondsToSelector:@selector(webView:willCloseFrame:)];
-    cache->delegateImplementsDidStartProvisionalLoadForFrame = [delegate respondsToSelector:@selector(webView:didStartProvisionalLoadForFrame:)];
-    cache->delegateImplementsDidReceiveTitleForFrame = [delegate respondsToSelector:@selector(webView:didReceiveTitle:forFrame:)];
-    cache->delegateImplementsDidCommitLoadForFrame = [delegate respondsToSelector:@selector(webView:didCommitLoadForFrame:)];
-    cache->delegateImplementsDidFailProvisionalLoadWithErrorForFrame = [delegate respondsToSelector:@selector(webView:didFailProvisionalLoadWithError:forFrame:)];
-    cache->delegateImplementsDidFailLoadWithErrorForFrame = [delegate respondsToSelector:@selector(webView:didFailLoadWithError:forFrame:)];
-    cache->delegateImplementsDidFinishLoadForFrame = [delegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)];
-    cache->delegateImplementsDidFirstLayoutInFrame = [delegate respondsToSelector:@selector(webView:didFirstLayoutInFrame:)];
-    cache->delegateImplementsDidReceiveIconForFrame = [delegate respondsToSelector:@selector(webView:didReceiveIcon:forFrame:)];
-    cache->delegateImplementsDidFinishDocumentLoadForFrame = [delegate respondsToSelector:@selector(webView:didFinishDocumentLoadForFrame:)];
-
 #if defined(OBJC_API_VERSION) && OBJC_API_VERSION > 0
 #define GET_OBJC_METHOD_IMP(class,selector) class_getMethodImplementation(class, selector)
 #else
 #define GET_OBJC_METHOD_IMP(class,selector) class_getInstanceMethod(class, selector)->method_imp
 #endif
 
-    if (cache->delegateImplementsDidClearWindowObjectForFrame)
-        cache->didClearWindowObjectForFrameFunc = (WebDidClearWindowObjectForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didClearWindowObject:forFrame:));
-    if (cache->delegateImplementsWindowScriptObjectAvailable)
-        cache->windowScriptObjectAvailableFunc = (WebWindowScriptObjectAvailableFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:windowScriptObjectAvailable:));
-    if (cache->delegateImplementsDidHandleOnloadEventsForFrame)
-        cache->didHandleOnloadEventsForFrameFunc = (WebDidHandleOnloadEventsForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didHandleOnloadEventsForFrame:));
-    if (cache->delegateImplementsDidReceiveServerRedirectForProvisionalLoadForFrame)
-        cache->didReceiveServerRedirectForProvisionalLoadForFrameFunc = (WebDidReceiveServerRedirectForProvisionalLoadForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didReceiveServerRedirectForProvisionalLoadForFrame:));
-    if (cache->delegateImplementsDidCancelClientRedirectForFrame)
-        cache->didCancelClientRedirectForFrameFunc = (WebDidCancelClientRedirectForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didCancelClientRedirectForFrame:));
-    if (cache->delegateImplementsWillPerformClientRedirectToURLDelayFireDateForFrame)
-        cache->willPerformClientRedirectToURLDelayFireDateForFrameFunc = (WebWillPerformClientRedirectToURLDelayFireDateForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:));
-    if (cache->delegateImplementsDidChangeLocationWithinPageForFrame)
-        cache->didChangeLocationWithinPageForFrameFunc = (WebDidChangeLocationWithinPageForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didChangeLocationWithinPageForFrame:));
-    if (cache->delegateImplementsWillCloseFrame)
-        cache->willCloseFrameFunc = (WebWillCloseFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:willCloseFrame:));
-    if (cache->delegateImplementsDidStartProvisionalLoadForFrame)
-        cache->didStartProvisionalLoadForFrameFunc = (WebDidStartProvisionalLoadForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didStartProvisionalLoadForFrame:));
-    if (cache->delegateImplementsDidReceiveTitleForFrame)
-        cache->didReceiveTitleForFrameFunc = (WebDidReceiveTitleForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didReceiveTitle:forFrame:));
-    if (cache->delegateImplementsDidCommitLoadForFrame)
-        cache->didCommitLoadForFrameFunc = (WebDidCommitLoadForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didCommitLoadForFrame:));
-    if (cache->delegateImplementsDidFailProvisionalLoadWithErrorForFrame)
-        cache->didFailProvisionalLoadWithErrorForFrameFunc = (WebDidFailProvisionalLoadWithErrorForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didFailProvisionalLoadWithError:forFrame:));
-    if (cache->delegateImplementsDidFailLoadWithErrorForFrame)
-        cache->didFailLoadWithErrorForFrameFunc = (WebDidFailLoadWithErrorForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didFailLoadWithError:forFrame:));
-    if (cache->delegateImplementsDidFinishLoadForFrame)
-        cache->didFinishLoadForFrameFunc = (WebDidFinishLoadForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didFinishLoadForFrame:));
-    if (cache->delegateImplementsDidFirstLayoutInFrame)
-        cache->didFirstLayoutInFrameFunc = (WebDidFirstLayoutInFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didFirstLayoutInFrame:));
-    if (cache->delegateImplementsDidReceiveIconForFrame)
-        cache->didReceiveIconForFrameFunc = (WebDidReceiveIconForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didReceiveIcon:forFrame:));
-    if (cache->delegateImplementsDidFinishDocumentLoadForFrame)
-        cache->didFinishDocumentLoadForFrameFunc = (WebDidFinishDocumentLoadForFrameFunc)GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didFinishDocumentLoadForFrame:));
-#undef GET_OBJC_METHOD_IMP
-}
+    if ([delegate respondsToSelector:@selector(webView:didClearWindowObject:forFrame:)])
+        cache->didClearWindowObjectForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didClearWindowObject:forFrame:));
+    if ([delegate respondsToSelector:@selector(webView:windowScriptObjectAvailable:)])
+        cache->windowScriptObjectAvailableFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:windowScriptObjectAvailable:));
+    if ([delegate respondsToSelector:@selector(webView:didHandleOnloadEventsForFrame:)])
+        cache->didHandleOnloadEventsForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didHandleOnloadEventsForFrame:));
+    if ([delegate respondsToSelector:@selector(webView:didReceiveServerRedirectForProvisionalLoadForFrame:)])
+        cache->didReceiveServerRedirectForProvisionalLoadForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didReceiveServerRedirectForProvisionalLoadForFrame:));
+    if ([delegate respondsToSelector:@selector(webView:didCancelClientRedirectForFrame:)])
+        cache->didCancelClientRedirectForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didCancelClientRedirectForFrame:));
+    if ([delegate respondsToSelector:@selector(webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:)])
+        cache->willPerformClientRedirectToURLDelayFireDateForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:));
+    if ([delegate respondsToSelector:@selector(webView:didChangeLocationWithinPageForFrame:)])
+        cache->didChangeLocationWithinPageForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didChangeLocationWithinPageForFrame:));
+    if ([delegate respondsToSelector:@selector(webView:willCloseFrame:)])
+        cache->willCloseFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:willCloseFrame:));
+    if ([delegate respondsToSelector:@selector(webView:didStartProvisionalLoadForFrame:)])
+        cache->didStartProvisionalLoadForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didStartProvisionalLoadForFrame:));
+    if ([delegate respondsToSelector:@selector(webView:didReceiveTitle:forFrame:)])
+        cache->didReceiveTitleForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didReceiveTitle:forFrame:));
+    if ([delegate respondsToSelector:@selector(webView:didCommitLoadForFrame:)])
+        cache->didCommitLoadForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didCommitLoadForFrame:));
+    if ([delegate respondsToSelector:@selector(webView:didFailProvisionalLoadWithError:forFrame:)])
+        cache->didFailProvisionalLoadWithErrorForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didFailProvisionalLoadWithError:forFrame:));
+    if ([delegate respondsToSelector:@selector(webView:didFailLoadWithError:forFrame:)])
+        cache->didFailLoadWithErrorForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didFailLoadWithError:forFrame:));
+    if ([delegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)])
+        cache->didFinishLoadForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didFinishLoadForFrame:));
+    if ([delegate respondsToSelector:@selector(webView:didFirstLayoutInFrame:)])
+        cache->didFirstLayoutInFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didFirstLayoutInFrame:));
+    if ([delegate respondsToSelector:@selector(webView:didReceiveIcon:forFrame:)])
+        cache->didReceiveIconForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didReceiveIcon:forFrame:));
+    if ([delegate respondsToSelector:@selector(webView:didFinishDocumentLoadForFrame:)])
+        cache->didFinishDocumentLoadForFrameFunc = GET_OBJC_METHOD_IMP(delegateClass, @selector(webView:didFinishDocumentLoadForFrame:));
 
-id WebViewGetFrameLoadDelegate(WebView *webView)
-{
-    return webView->_private->frameLoadDelegate;
+#undef GET_OBJC_METHOD_IMP
 }
 
 WebFrameLoadDelegateImplementationCache WebViewGetFrameLoadDelegateImplementations(WebView *webView)
@@ -1063,35 +1032,36 @@ WebFrameLoadDelegateImplementationCache WebViewGetFrameLoadDelegateImplementatio
     return webView->_private->frameLoadDelegateImplementations;
 }
 
-- _policyDelegateForwarder
+- (id)_policyDelegateForwarder
 {
     if (!_private->policyDelegateForwarder)
-        _private->policyDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget: [self policyDelegate] defaultTarget: [WebDefaultPolicyDelegate sharedPolicyDelegate] templateClass: [WebDefaultPolicyDelegate class]];
+        _private->policyDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget:_private->policyDelegate defaultTarget:[WebDefaultPolicyDelegate sharedPolicyDelegate] catchExceptions:_private->catchesDelegateExceptions];
     return _private->policyDelegateForwarder;
 }
 
-- _UIDelegateForwarder
+- (id)_UIDelegateForwarder
 {
     if (!_private->UIDelegateForwarder)
-        _private->UIDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget: [self UIDelegate] defaultTarget: [WebDefaultUIDelegate sharedUIDelegate] templateClass: [WebDefaultUIDelegate class]];
+        _private->UIDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget:_private->UIDelegate defaultTarget:[WebDefaultUIDelegate sharedUIDelegate] catchExceptions:_private->catchesDelegateExceptions];
     return _private->UIDelegateForwarder;
 }
 
-- _editingDelegateForwarder
+- (id)_editingDelegateForwarder
 {
     // This can be called during window deallocation by QTMovieView in the QuickTime Cocoa Plug-in.
     // Not sure if that is a bug or not.
     if (!_private)
         return nil;
+
     if (!_private->editingDelegateForwarder)
-        _private->editingDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget: [self editingDelegate] defaultTarget: [WebDefaultEditingDelegate sharedEditingDelegate] templateClass: [WebDefaultEditingDelegate class]];
+        _private->editingDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget:_private->editingDelegate defaultTarget:[WebDefaultEditingDelegate sharedEditingDelegate] catchExceptions:_private->catchesDelegateExceptions];
     return _private->editingDelegateForwarder;
 }
 
-- _scriptDebugDelegateForwarder
+- (id)_scriptDebugDelegateForwarder
 {
     if (!_private->scriptDebugDelegateForwarder)
-        _private->scriptDebugDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget: [self scriptDebugDelegate] defaultTarget: [WebDefaultScriptDebugDelegate sharedScriptDebugDelegate] templateClass: [WebDefaultScriptDebugDelegate class]];
+        _private->scriptDebugDelegateForwarder = [[_WebSafeForwarder alloc] initWithTarget:_private->scriptDebugDelegate defaultTarget:[WebDefaultScriptDebugDelegate sharedScriptDebugDelegate] catchExceptions:_private->catchesDelegateExceptions];
     return _private->scriptDebugDelegateForwarder;
 }
 
@@ -1615,55 +1585,56 @@ WebFrameLoadDelegateImplementationCache WebViewGetFrameLoadDelegateImplementatio
     _private->page->clearUndoRedoOperations();
 }
 
+- (void)_setCatchesDelegateExceptions:(BOOL)f
+{
+    _private->catchesDelegateExceptions = f;
+}
+
+- (BOOL)_catchesDelegateExceptions
+{
+    return _private->catchesDelegateExceptions;
+}
+
 @end
 
 @implementation _WebSafeForwarder
 
-- initWithTarget: t defaultTarget: dt templateClass: (Class)aClass
+// Used to send messages to delegates that implement informal protocols.
+
+- (id)initWithTarget:(id)t defaultTarget:(id)dt catchExceptions:(BOOL)c
 {
     self = [super init];
     if (!self)
         return nil;
-    
     target = t; // Non retained.
     defaultTarget = dt;
-    templateClass = aClass;
+    catchExceptions = c;
     return self;
 }
 
-// Used to send messages to delegates that implement informal protocols.
-+ safeForwarderWithTarget: t defaultTarget: dt templateClass: (Class)aClass;
+- (void)forwardInvocation:(NSInvocation *)invocation
 {
-    return [[[_WebSafeForwarder alloc] initWithTarget: t defaultTarget: dt templateClass: aClass] autorelease];
-}
+    if ([target respondsToSelector:[invocation selector]]) {
+        if (catchExceptions) {
+            @try {
+                [invocation invokeWithTarget:target];
+            } @catch(id exception) {
+                ReportDiscardedDelegateException([invocation selector], exception);
+            }
+        } else
+            [invocation invokeWithTarget:target];
+        return;
+    }
 
-#ifndef NDEBUG
-NSMutableDictionary *countInvocations;
-#endif
+    if ([defaultTarget respondsToSelector:[invocation selector]])
+        [invocation invokeWithTarget:defaultTarget];
 
-- (void)forwardInvocation:(NSInvocation *)anInvocation
-{
-#ifndef NDEBUG
-    if (!countInvocations){
-        countInvocations = [[NSMutableDictionary alloc] init];
-    }
-    NSNumber *count = [countInvocations objectForKey: NSStringFromSelector([anInvocation selector])];
-    if (!count)
-        count = [NSNumber numberWithInt: 1];
-    else
-        count = [NSNumber numberWithInt: [count intValue] + 1];
-    [countInvocations setObject: count forKey: NSStringFromSelector([anInvocation selector])];
-#endif
-    if ([target respondsToSelector: [anInvocation selector]])
-        [anInvocation invokeWithTarget: target];
-    else if ([defaultTarget respondsToSelector: [anInvocation selector]])
-        [anInvocation invokeWithTarget: defaultTarget];
     // Do nothing quietly if method not implemented.
 }
 
 - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
 {
-    return [templateClass instanceMethodSignatureForSelector: aSelector];
+    return [defaultTarget methodSignatureForSelector:aSelector];
 }
 
 @end
@@ -1822,6 +1793,7 @@ NSMutableDictionary *countInvocations;
 
 - (void)_commonInitializationWithFrameName:(NSString *)frameName groupName:(NSString *)groupName
 {
+    _private->catchesDelegateExceptions = YES;
     _private->mainFrameDocumentReady = NO;
     _private->drawsBackground = YES;
     _private->smartInsertDeleteEnabled = YES;
@@ -2846,12 +2818,7 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
 - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item
 {
     BOOL result = [self validateUserInterfaceItemWithoutDelegate:item];
-
-    id ud = [self UIDelegate];
-    if (ud && [ud respondsToSelector:@selector(webView:validateUserInterfaceItem:defaultValidation:)])
-        return [ud webView:self validateUserInterfaceItem:item defaultValidation:result];
-
-    return result;
+    return CallUIDelegateReturningBoolean(result, self, @selector(webView:validateUserInterfaceItem:defaultValidation:), item, result);
 }
 
 @end
@@ -3115,28 +3082,12 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
 
 - (float)_headerHeight
 {
-    if ([[self UIDelegate] respondsToSelector:@selector(webViewHeaderHeight:)]) {
-        return [[self UIDelegate] webViewHeaderHeight:self];
-    }
-    
-#ifdef DEBUG_HEADER_AND_FOOTER
-    return 25;
-#else
-    return 0;
-#endif
+    return CallUIDelegateReturningFloat(self, @selector(webViewHeaderHeight:));
 }
 
 - (float)_footerHeight
 {
-    if ([[self UIDelegate] respondsToSelector:@selector(webViewFooterHeight:)]) {
-        return [[self UIDelegate] webViewFooterHeight:self];
-    }
-    
-#ifdef DEBUG_HEADER_AND_FOOTER
-    return 50;
-#else
-    return 0;
-#endif
+    return CallUIDelegateReturningFloat(self, @selector(webViewFooterHeight:));
 }
 
 - (void)_drawHeaderInRect:(NSRect)rect
@@ -3148,14 +3099,18 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
     NSRectFill(rect);
     [currentContext restoreGraphicsState];
 #endif
-    
-    if ([[self UIDelegate] respondsToSelector:@selector(webView:drawHeaderInRect:)]) {
-        NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
-        [currentContext saveGraphicsState];
-        NSRectClip(rect);
-        [[self UIDelegate] webView:self drawHeaderInRect:rect]; 
-        [currentContext restoreGraphicsState];
-    }
+
+    SEL selector = @selector(webView:drawHeaderInRect:);
+    if (![_private->UIDelegate respondsToSelector:selector])
+        return;
+
+    NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
+    [currentContext saveGraphicsState];
+
+    NSRectClip(rect);
+    CallUIDelegate(self, selector, rect);
+
+    [currentContext restoreGraphicsState];
 }
 
 - (void)_drawFooterInRect:(NSRect)rect
@@ -3168,13 +3123,17 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
     [currentContext restoreGraphicsState];
 #endif
     
-    if ([[self UIDelegate] respondsToSelector:@selector(webView:drawFooterInRect:)]) {
-        NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
-        [currentContext saveGraphicsState];
-        NSRectClip(rect);
-        [[self UIDelegate] webView:self drawFooterInRect:rect];
-        [currentContext restoreGraphicsState];
-    }
+    SEL selector = @selector(webView:drawFooterInRect:);
+    if (![_private->UIDelegate respondsToSelector:selector])
+        return;
+
+    NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
+    [currentContext saveGraphicsState];
+
+    NSRectClip(rect);
+    CallUIDelegate(self, selector, rect);
+
+    [currentContext restoreGraphicsState];
 }
 
 - (void)_adjustPrintingMarginsForHeaderAndFooter
@@ -3275,7 +3234,6 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
     // FIXME: This quirk is needed due to <rdar://problem/4985321> - We can phase it out once Aperture can adopt the new behavior on their end
     if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_APERTURE_QUIRK) && [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Aperture"])
         return YES;
-        
     return [[self _editingDelegateForwarder] webView:self shouldChangeSelectedDOMRange:currentRange toDOMRange:proposedRange affinity:selectionAffinity stillSelecting:flag];
 }
 
@@ -3917,3 +3875,458 @@ static WebFrameView *containingFrameView(NSView *view)
 }
 
 @end
+
+// We use these functions to call the delegates and block exceptions. These functions are
+// declared inside a WebView category to get direct access to the delegate data memebers,
+// preventing more ObjC message dispatch and compensating for the expense of the @try/@catch.
+
+@implementation WebView (WebCallDelegateFunctions)
+
+#if !(defined(__i386__) || defined(__x86_64__))
+typedef double (*ObjCMsgSendFPRet)(id, SEL, ...);
+static const ObjCMsgSendFPRet objc_msgSend_fpret = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend);
+#endif
+
+static inline id CallDelegate(WebView *self, id delegate, SEL selector)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return objc_msgSend(delegate, selector, self);
+    @try {
+        return objc_msgSend(delegate, selector, self);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return objc_msgSend(delegate, selector, self, object);
+    @try {
+        return objc_msgSend(delegate, selector, self, object);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline id CallDelegate(WebView *self, id delegate, SEL selector, NSRect rect)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return reinterpret_cast<id (*)(id, SEL, WebView *, NSRect)>(objc_msgSend)(delegate, selector, self, rect);
+    @try {
+        return reinterpret_cast<id (*)(id, SEL, WebView *, NSRect)>(objc_msgSend)(delegate, selector, self, rect);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object1, id object2)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return objc_msgSend(delegate, selector, self, object1, object2);
+    @try {
+        return objc_msgSend(delegate, selector, self, object1, object2);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object, BOOL boolean)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return objc_msgSend(delegate, selector, self, object, boolean);
+    @try {
+        return objc_msgSend(delegate, selector, self, object, boolean);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object1, id object2, id object3)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return objc_msgSend(delegate, selector, self, object1, object2, object3);
+    @try {
+        return objc_msgSend(delegate, selector, self, object1, object2, object3);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object, NSUInteger integer)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return objc_msgSend(delegate, selector, self, object, integer);
+    @try {
+        return objc_msgSend(delegate, selector, self, object, integer);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline float CallDelegateReturningFloat(WebView *self, id delegate, SEL selector)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return 0.0f;
+    if (!self->_private->catchesDelegateExceptions)
+        return static_cast<float>(objc_msgSend_fpret(delegate, selector, self));
+    @try {
+        return static_cast<float>(objc_msgSend_fpret(delegate, selector, self));
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return 0.0f;
+}
+
+static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return result;
+    if (!self->_private->catchesDelegateExceptions)
+        return reinterpret_cast<BOOL (*)(id, SEL, WebView *)>(objc_msgSend)(delegate, selector, self);
+    @try {
+        return reinterpret_cast<BOOL (*)(id, SEL, WebView *)>(objc_msgSend)(delegate, selector, self);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return result;
+}
+
+static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return result;
+    if (!self->_private->catchesDelegateExceptions)
+        return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id)>(objc_msgSend)(delegate, selector, self, object);
+    @try {
+        return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id)>(objc_msgSend)(delegate, selector, self, object);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return result;
+}
+
+static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object, BOOL boolean)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return result;
+    if (!self->_private->catchesDelegateExceptions)
+        return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, BOOL)>(objc_msgSend)(delegate, selector, self, object, boolean);
+    @try {
+        return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, BOOL)>(objc_msgSend)(delegate, selector, self, object, boolean);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return result;
+}
+
+static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object1, id object2)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return result;
+    if (!self->_private->catchesDelegateExceptions)
+        return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(delegate, selector, self, object1, object2);
+    @try {
+        return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(delegate, selector, self, object1, object2);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return result;
+}
+
+static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector)
+{
+    if (!delegate)
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return implementation(delegate, selector, self);
+    @try {
+        return implementation(delegate, selector, self);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object)
+{
+    if (!delegate)
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return implementation(delegate, selector, self, object);
+    @try {
+        return implementation(delegate, selector, self, object);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2)
+{
+    if (!delegate)
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return implementation(delegate, selector, self, object1, object2);
+    @try {
+        return implementation(delegate, selector, self, object1, object2);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3)
+{
+    if (!delegate)
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return implementation(delegate, selector, self, object1, object2, object3);
+    @try {
+        return implementation(delegate, selector, self, object1, object2, object3);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3, id object4)
+{
+    if (!delegate)
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return implementation(delegate, selector, self, object1, object2, object3, object4);
+    @try {
+        return implementation(delegate, selector, self, object1, object2, object3, object4);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2)
+{
+    if (!delegate)
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return implementation(delegate, selector, self, object1, integer, object2);
+    @try {
+        return implementation(delegate, selector, self, object1, integer, object2);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, NSInteger integer, id object3)
+{
+    if (!delegate)
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return implementation(delegate, selector, self, object1, object2, integer, object3);
+    @try {
+        return implementation(delegate, selector, self, object1, object2, integer, object3);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSTimeInterval interval, id object2, id object3)
+{
+    if (!delegate)
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return implementation(delegate, selector, self, object1, interval, object2, object3);
+    @try {
+        return implementation(delegate, selector, self, object1, interval, object2, object3);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+id CallUIDelegate(WebView *self, SEL selector)
+{
+    return CallDelegate(self, self->_private->UIDelegate, selector);
+}
+
+id CallUIDelegate(WebView *self, SEL selector, id object)
+{
+    return CallDelegate(self, self->_private->UIDelegate, selector, object);
+}
+
+id CallUIDelegate(WebView *self, SEL selector, id object, BOOL boolean)
+{
+    return CallDelegate(self, self->_private->UIDelegate, selector, object, boolean);
+}
+
+id CallUIDelegate(WebView *self, SEL selector, NSRect rect)
+{
+    return CallDelegate(self, self->_private->UIDelegate, selector, rect);
+}
+
+id CallUIDelegate(WebView *self, SEL selector, id object1, id object2)
+{
+    return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2);
+}
+
+id CallUIDelegate(WebView *self, SEL selector, id object1, id object2, id object3)
+{
+    return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2, object3);
+}
+
+id CallUIDelegate(WebView *self, SEL selector, id object, NSUInteger integer)
+{
+    return CallDelegate(self, self->_private->UIDelegate, selector, object, integer);
+}
+
+float CallUIDelegateReturningFloat(WebView *self, SEL selector)
+{
+    return CallDelegateReturningFloat(self, self->_private->UIDelegate, selector);
+}
+
+BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector)
+{
+    return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector);
+}
+
+BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object)
+{
+    return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object);
+}
+
+BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object, BOOL boolean)
+{
+    return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object, boolean);
+}
+
+BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, id object2)
+{
+    return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object1, object2);
+}
+
+id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector)
+{
+    return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector);
+}
+
+id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object)
+{
+    return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object);
+}
+
+id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
+{
+    return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2);
+}
+
+id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
+{
+    return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3);
+}
+
+id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4)
+{
+    return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3, object4);
+}
+
+id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSTimeInterval interval, id object2, id object3)
+{
+    return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, interval, object2, object3);
+}
+
+id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
+{
+    return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2);
+}
+
+id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
+{
+    return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3);
+}
+
+id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4)
+{
+    return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3, object4);
+}
+
+id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2)
+{
+    return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, integer, object2);
+}
+
+id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3)
+{
+    return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, integer, object3);
+}
+
+// The form delegate needs to have it's own implementation, because the first argument is never the WebView
+
+id CallFormDelegate(WebView *self, SEL selector, id object1, id object2)
+{
+    id delegate = self->_private->formDelegate;
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return objc_msgSend(delegate, selector, object1, object2);
+    @try {
+        return objc_msgSend(delegate, selector, object1, object2);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+id CallFormDelegate(WebView *self, SEL selector, id object1, id object2, id object3, id object4, id object5)
+{
+    id delegate = self->_private->formDelegate;
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return nil;
+    if (!self->_private->catchesDelegateExceptions)
+        return objc_msgSend(delegate, selector, object1, object2, object3, object4, object5);
+    @try {
+        return objc_msgSend(delegate, selector, object1, object2, object3, object4, object5);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return nil;
+}
+
+BOOL CallFormDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, SEL selectorArg, id object2)
+{
+    id delegate = self->_private->formDelegate;
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return result;
+    if (!self->_private->catchesDelegateExceptions)
+        return reinterpret_cast<BOOL (*)(id, SEL, id, SEL, id)>(objc_msgSend)(delegate, selector, object1, selectorArg, object2);
+    @try {
+        return reinterpret_cast<BOOL (*)(id, SEL, id, SEL, id)>(objc_msgSend)(delegate, selector, object1, selectorArg, object2);
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return result;
+}
+
+@end
index 50b2d21e8f7e2b5c265085736961bff68f24bd2b..171ae720703ca31814c92583153a18cfb0ee2c6c 100644 (file)
@@ -65,13 +65,8 @@ typedef WebCore::Page WebCorePage;
 #endif
 @end
 
-id WebViewGetResourceLoadDelegate(WebView *webView);
-WebResourceDelegateImplementationCache WebViewGetResourceLoadDelegateImplementations(WebView *webView);
-
-id WebViewGetFrameLoadDelegate(WebView *webView);
-WebFrameLoadDelegateImplementationCache WebViewGetFrameLoadDelegateImplementations(WebView *webView);
-
 @interface WebView (WebViewMiscInternal)
+
 + (void)_initializeCacheSizesIfNecessary;
 - (WebCorePage*)page;
 - (NSMenu *)_menuForElement:(NSDictionary *)element defaultItems:(NSArray *)items;
@@ -115,4 +110,76 @@ WebFrameLoadDelegateImplementationCache WebViewGetFrameLoadDelegateImplementatio
 - (id)_objectForIdentifier:(unsigned long)identifier;
 - (void)_removeObjectForIdentifier:(unsigned long)identifier;
 - (BOOL)_becomingFirstResponderFromOutside;
+
 @end
+
+typedef struct _WebResourceDelegateImplementationCache {
+    IMP didCancelAuthenticationChallengeFunc;
+    IMP didReceiveAuthenticationChallengeFunc;
+    IMP identifierForRequestFunc;
+    IMP willSendRequestFunc;
+    IMP didReceiveResponseFunc;
+    IMP didReceiveContentLengthFunc;
+    IMP didFinishLoadingFromDataSourceFunc;
+    IMP didFailLoadingWithErrorFromDataSourceFunc;
+    IMP didLoadResourceFromMemoryCacheFunc;
+    IMP willCacheResponseFunc;
+    IMP plugInFailedWithErrorFunc;
+} WebResourceDelegateImplementationCache;
+
+typedef struct _WebFrameLoadDelegateImplementationCache {
+    IMP didClearWindowObjectForFrameFunc;
+    IMP windowScriptObjectAvailableFunc;
+    IMP didHandleOnloadEventsForFrameFunc;
+    IMP didReceiveServerRedirectForProvisionalLoadForFrameFunc;
+    IMP didCancelClientRedirectForFrameFunc;
+    IMP willPerformClientRedirectToURLDelayFireDateForFrameFunc;
+    IMP didChangeLocationWithinPageForFrameFunc;
+    IMP willCloseFrameFunc;
+    IMP didStartProvisionalLoadForFrameFunc;
+    IMP didReceiveTitleForFrameFunc;
+    IMP didCommitLoadForFrameFunc;
+    IMP didFailProvisionalLoadWithErrorForFrameFunc;
+    IMP didFailLoadWithErrorForFrameFunc;
+    IMP didFinishLoadForFrameFunc;
+    IMP didFirstLayoutInFrameFunc;
+    IMP didReceiveIconForFrameFunc;
+    IMP didFinishDocumentLoadForFrameFunc;
+} WebFrameLoadDelegateImplementationCache;
+
+WebResourceDelegateImplementationCache WebViewGetResourceLoadDelegateImplementations(WebView *webView);
+WebFrameLoadDelegateImplementationCache WebViewGetFrameLoadDelegateImplementations(WebView *webView);
+
+#ifdef __cplusplus
+
+id CallFormDelegate(WebView *, SEL, id, id);
+id CallFormDelegate(WebView *self, SEL selector, id object1, id object2, id object3, id object4, id object5);
+BOOL CallFormDelegateReturningBoolean(BOOL, WebView *, SEL, id, SEL, id);
+
+id CallUIDelegate(WebView *, SEL);
+id CallUIDelegate(WebView *, SEL, id);
+id CallUIDelegate(WebView *, SEL, NSRect);
+id CallUIDelegate(WebView *, SEL, id, id);
+id CallUIDelegate(WebView *, SEL, id, BOOL);
+id CallUIDelegate(WebView *, SEL, id, id, id);
+id CallUIDelegate(WebView *, SEL, id, NSUInteger);
+float CallUIDelegateReturningFloat(WebView *, SEL);
+BOOL CallUIDelegateReturningBoolean(BOOL, WebView *, SEL);
+BOOL CallUIDelegateReturningBoolean(BOOL, WebView *, SEL, id);
+BOOL CallUIDelegateReturningBoolean(BOOL, WebView *, SEL, id, id);
+BOOL CallUIDelegateReturningBoolean(BOOL, WebView *, SEL, id, BOOL);
+
+id CallFrameLoadDelegate(IMP, WebView *, SEL);
+id CallFrameLoadDelegate(IMP, WebView *, SEL, id);
+id CallFrameLoadDelegate(IMP, WebView *, SEL, id, id);
+id CallFrameLoadDelegate(IMP, WebView *, SEL, id, id, id);
+id CallFrameLoadDelegate(IMP, WebView *, SEL, id, id, id, id);
+id CallFrameLoadDelegate(IMP, WebView *, SEL, id, NSTimeInterval, id, id);
+
+id CallResourceLoadDelegate(IMP, WebView *, SEL, id, id);
+id CallResourceLoadDelegate(IMP, WebView *, SEL, id, id, id);
+id CallResourceLoadDelegate(IMP, WebView *, SEL, id, id, id, id);
+id CallResourceLoadDelegate(IMP, WebView *, SEL, id, NSInteger, id);
+id CallResourceLoadDelegate(IMP, WebView *, SEL, id, id, NSInteger, id);
+
+#endif
index d11e7280c5ef3eb496d2232601a1cf04be81bd53..e312494c743ee617d98bfadbe20a96246f0325af 100644 (file)
 
 @protocol WebFormDelegate;
 
-typedef void (*WebDidCancelAuthenticationChallengeFunc)(id, SEL, WebView *, id, NSURLAuthenticationChallenge *, WebDataSource *);
-typedef void (*WebDidReceiveAuthenticationChallengeFunc)(id, SEL, WebView *, id, NSURLAuthenticationChallenge *, WebDataSource *);
-typedef id (*WebIdentifierForRequestFunc)(id, SEL, WebView *, NSURLRequest *, WebDataSource *);
-typedef NSURLRequest *(*WebWillSendRequestFunc)(id, SEL, WebView *, id, NSURLRequest *, NSURLResponse *, WebDataSource *);
-typedef void (*WebDidReceiveResponseFunc)(id, SEL, WebView *, id, NSURLResponse *, WebDataSource *);
-typedef void (*WebDidReceiveContentLengthFunc)(id, SEL, WebView *, id, WebNSInteger, WebDataSource *);
-typedef void (*WebDidFinishLoadingFromDataSourceFunc)(id, SEL, WebView *, id, WebDataSource *);
-typedef void (*WebDidFailLoadingWithErrorFromDataSourceFunc)(id, SEL, WebView *, id, NSError *, WebDataSource *);
-typedef void (*WebDidLoadResourceFromMemoryCacheFunc)(id, SEL, WebView *, NSURLRequest *, NSURLResponse *, WebNSInteger, WebDataSource *);
-typedef NSCachedURLResponse *(*WebWillCacheResponseFunc)(id, SEL, WebView *, id, NSCachedURLResponse *, WebDataSource *);
-
-typedef struct _WebResourceDelegateImplementationCache {
-    uint delegateImplementsDidCancelAuthenticationChallenge:1;
-    uint delegateImplementsDidReceiveAuthenticationChallenge:1;
-    uint delegateImplementsDidReceiveResponse:1;
-    uint delegateImplementsDidReceiveContentLength:1;
-    uint delegateImplementsDidFinishLoadingFromDataSource:1;
-    uint delegateImplementsDidFailLoadingWithErrorFromDataSource:1;
-    uint delegateImplementsWillSendRequest:1;
-    uint delegateImplementsIdentifierForRequest:1;
-    uint delegateImplementsDidLoadResourceFromMemoryCache:1;
-    uint delegateImplementsWillCacheResponse:1;
-
-    WebDidCancelAuthenticationChallengeFunc didCancelAuthenticationChallengeFunc;
-    WebDidReceiveAuthenticationChallengeFunc didReceiveAuthenticationChallengeFunc;
-    WebIdentifierForRequestFunc identifierForRequestFunc;
-    WebWillSendRequestFunc willSendRequestFunc;
-    WebDidReceiveResponseFunc didReceiveResponseFunc;
-    WebDidReceiveContentLengthFunc didReceiveContentLengthFunc;
-    WebDidFinishLoadingFromDataSourceFunc didFinishLoadingFromDataSourceFunc;
-    WebDidFailLoadingWithErrorFromDataSourceFunc didFailLoadingWithErrorFromDataSourceFunc;
-    WebDidLoadResourceFromMemoryCacheFunc didLoadResourceFromMemoryCacheFunc;
-    WebWillCacheResponseFunc willCacheResponseFunc;
-} WebResourceDelegateImplementationCache;
-
-typedef void (*WebDidClearWindowObjectForFrameFunc)(id, SEL, WebView *, WebScriptObject *, WebFrame *);
-typedef void (*WebWindowScriptObjectAvailableFunc)(id, SEL, WebView *, WebScriptObject *);
-typedef void (*WebDidHandleOnloadEventsForFrameFunc)(id, SEL, WebView *, WebFrame *);
-typedef void (*WebDidReceiveServerRedirectForProvisionalLoadForFrameFunc)(id, SEL, WebView *, WebFrame *);
-typedef void (*WebDidCancelClientRedirectForFrameFunc)(id, SEL, WebView *, WebFrame *);
-typedef void (*WebWillPerformClientRedirectToURLDelayFireDateForFrameFunc)(id, SEL, WebView *, NSURL *, double, NSDate *, WebFrame *);
-typedef void (*WebDidChangeLocationWithinPageForFrameFunc)(id, SEL, WebView *, WebFrame *);
-typedef void (*WebWillCloseFrameFunc)(id, SEL, WebView *, WebFrame *);
-typedef void (*WebDidStartProvisionalLoadForFrameFunc)(id, SEL, WebView *, WebFrame *);
-typedef void (*WebDidReceiveTitleForFrameFunc)(id, SEL, WebView *, NSString *, WebFrame *);
-typedef void (*WebDidCommitLoadForFrameFunc)(id, SEL, WebView *, WebFrame *);
-typedef void (*WebDidFailProvisionalLoadWithErrorForFrameFunc)(id, SEL, WebView *, NSError *, WebFrame *);
-typedef void (*WebDidFailLoadWithErrorForFrameFunc)(id, SEL, WebView *, NSError *, WebFrame *);
-typedef void (*WebDidFinishLoadForFrameFunc)(id, SEL, WebView *, WebFrame *);
-typedef void (*WebDidFirstLayoutInFrameFunc)(id, SEL, WebView *, WebFrame *);
-typedef void (*WebDidReceiveIconForFrameFunc)(id, SEL, WebView *, NSImage *, WebFrame *);
-typedef void (*WebDidFinishDocumentLoadForFrameFunc)(id, SEL, WebView *, WebFrame *);
-
-typedef struct _WebFrameLoadDelegateImplementationCache {
-    uint delegateImplementsDidClearWindowObjectForFrame: 1;
-    uint delegateImplementsWindowScriptObjectAvailable: 1;
-    uint delegateImplementsDidHandleOnloadEventsForFrame: 1;
-    uint delegateImplementsDidReceiveServerRedirectForProvisionalLoadForFrame: 1;
-    uint delegateImplementsDidCancelClientRedirectForFrame: 1;
-    uint delegateImplementsWillPerformClientRedirectToURLDelayFireDateForFrame: 1;
-    uint delegateImplementsDidChangeLocationWithinPageForFrame: 1;
-    uint delegateImplementsWillCloseFrame: 1;
-    uint delegateImplementsDidStartProvisionalLoadForFrame: 1;
-    uint delegateImplementsDidReceiveTitleForFrame: 1;
-    uint delegateImplementsDidCommitLoadForFrame: 1;
-    uint delegateImplementsDidFailProvisionalLoadWithErrorForFrame: 1;
-    uint delegateImplementsDidFailLoadWithErrorForFrame: 1;
-    uint delegateImplementsDidFinishLoadForFrame: 1;
-    uint delegateImplementsDidFirstLayoutInFrame: 1;
-    uint delegateImplementsDidReceiveIconForFrame: 1;
-    uint delegateImplementsDidFinishDocumentLoadForFrame: 1;
-
-    WebDidClearWindowObjectForFrameFunc didClearWindowObjectForFrameFunc;
-    WebWindowScriptObjectAvailableFunc windowScriptObjectAvailableFunc;
-    WebDidHandleOnloadEventsForFrameFunc didHandleOnloadEventsForFrameFunc;
-    WebDidReceiveServerRedirectForProvisionalLoadForFrameFunc didReceiveServerRedirectForProvisionalLoadForFrameFunc;
-    WebDidCancelClientRedirectForFrameFunc didCancelClientRedirectForFrameFunc;
-    WebWillPerformClientRedirectToURLDelayFireDateForFrameFunc willPerformClientRedirectToURLDelayFireDateForFrameFunc;
-    WebDidChangeLocationWithinPageForFrameFunc didChangeLocationWithinPageForFrameFunc;
-    WebWillCloseFrameFunc willCloseFrameFunc;
-    WebDidStartProvisionalLoadForFrameFunc didStartProvisionalLoadForFrameFunc;
-    WebDidReceiveTitleForFrameFunc didReceiveTitleForFrameFunc;
-    WebDidCommitLoadForFrameFunc didCommitLoadForFrameFunc;
-    WebDidFailProvisionalLoadWithErrorForFrameFunc didFailProvisionalLoadWithErrorForFrameFunc;
-    WebDidFailLoadWithErrorForFrameFunc didFailLoadWithErrorForFrameFunc;
-    WebDidFinishLoadForFrameFunc didFinishLoadForFrameFunc;
-    WebDidFirstLayoutInFrameFunc didFirstLayoutInFrameFunc;
-    WebDidReceiveIconForFrameFunc didReceiveIconForFrameFunc;
-    WebDidFinishDocumentLoadForFrameFunc didFinishDocumentLoadForFrameFunc;
-} WebFrameLoadDelegateImplementationCache;
-
 extern NSString *_WebCanGoBackKey;
 extern NSString *_WebCanGoForwardKey;
 extern NSString *_WebEstimatedProgressKey;
@@ -334,6 +243,9 @@ Could be worth adding to the API.
 + (void)_setShouldUseFontSmoothing:(BOOL)f;
 + (BOOL)_shouldUseFontSmoothing;
 
+- (void)_setCatchesDelegateExceptions:(BOOL)f;
+- (BOOL)_catchesDelegateExceptions;
+
 // These two methods are useful for a test harness that needs a consistent appearance for the focus rings
 // regardless of OS X version.
 + (void)_setUsesTestModeFocusRingColor:(BOOL)f;
@@ -461,16 +373,6 @@ Could be worth adding to the API.
 - (void)_replaceSelectionWithNode:(DOMNode *)node matchStyle:(BOOL)matchStyle;
 @end
 
-@interface _WebSafeForwarder : NSObject
-{
-    id target; // Non-retained. Don't retain delegates.
-    id defaultTarget;
-    Class templateClass;
-}
-- (id)initWithTarget:(id)t defaultTarget:(id)dt templateClass:(Class)aClass;
-+ (id)safeForwarderWithTarget:(id)t defaultTarget:(id)dt templateClass:(Class)aClass;
-@end
-
 @interface NSObject (WebFrameLoadDelegatePrivate)
 - (void)webView:(WebView *)sender didFirstLayoutInFrame:(WebFrame *)frame;