Home | History | Annotate | Download | only in WebView
      1 /*
      2  * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
      3  * Copyright (C) 2006 David Smith (catfish.man (at) gmail.com)
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1.  Redistributions of source code must retain the above copyright
     10  *     notice, this list of conditions and the following disclaimer.
     11  * 2.  Redistributions in binary form must reproduce the above copyright
     12  *     notice, this list of conditions and the following disclaimer in the
     13  *     documentation and/or other materials provided with the distribution.
     14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     15  *     its contributors may be used to endorse or promote products derived
     16  *     from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #import "WebDelegateImplementationCaching.h"
     31 
     32 #import "WebKitLogging.h"
     33 #import "WebView.h"
     34 #import "WebViewData.h"
     35 #import <objc/objc-runtime.h>
     36 
     37 @implementation WebView (WebDelegateImplementationCaching)
     38 
     39 WebResourceDelegateImplementationCache* WebViewGetResourceLoadDelegateImplementations(WebView *webView)
     40 {
     41     static WebResourceDelegateImplementationCache empty;
     42     if (!webView)
     43         return &empty;
     44     return &webView->_private->resourceLoadDelegateImplementations;
     45 }
     46 
     47 WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementations(WebView *webView)
     48 {
     49     static WebFrameLoadDelegateImplementationCache empty;
     50     if (!webView)
     51         return &empty;
     52     return &webView->_private->frameLoadDelegateImplementations;
     53 }
     54 
     55 WebScriptDebugDelegateImplementationCache* WebViewGetScriptDebugDelegateImplementations(WebView *webView)
     56 {
     57     static WebScriptDebugDelegateImplementationCache empty;
     58     if (!webView)
     59         return &empty;
     60     return &webView->_private->scriptDebugDelegateImplementations;
     61 }
     62 
     63 WebHistoryDelegateImplementationCache* WebViewGetHistoryDelegateImplementations(WebView *webView)
     64 {
     65     static WebHistoryDelegateImplementationCache empty;
     66     if (!webView)
     67         return &empty;
     68     return &webView->_private->historyDelegateImplementations;
     69 }
     70 
     71 // We use these functions to call the delegates and block exceptions. These functions are
     72 // declared inside a WebView category to get direct access to the delegate data memebers,
     73 // preventing more ObjC message dispatch and compensating for the expense of the @try/@catch.
     74 
     75 typedef float (*ObjCMsgSendFPRet)(id, SEL, ...);
     76 #if defined(__i386__)
     77 static const ObjCMsgSendFPRet objc_msgSend_float_return = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend_fpret);
     78 #else
     79 static const ObjCMsgSendFPRet objc_msgSend_float_return = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend);
     80 #endif
     81 
     82 static inline id CallDelegate(WebView *self, id delegate, SEL selector)
     83 {
     84     if (!delegate || ![delegate respondsToSelector:selector])
     85         return nil;
     86     if (!self->_private->catchesDelegateExceptions)
     87         return objc_msgSend(delegate, selector, self);
     88     @try {
     89         return objc_msgSend(delegate, selector, self);
     90     } @catch(id exception) {
     91         ReportDiscardedDelegateException(selector, exception);
     92     }
     93     return nil;
     94 }
     95 
     96 static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object)
     97 {
     98     if (!delegate || ![delegate respondsToSelector:selector])
     99         return nil;
    100     if (!self->_private->catchesDelegateExceptions)
    101         return objc_msgSend(delegate, selector, self, object);
    102     @try {
    103         return objc_msgSend(delegate, selector, self, object);
    104     } @catch(id exception) {
    105         ReportDiscardedDelegateException(selector, exception);
    106     }
    107     return nil;
    108 }
    109 
    110 static inline id CallDelegate(WebView *self, id delegate, SEL selector, NSRect rect)
    111 {
    112     if (!delegate || ![delegate respondsToSelector:selector])
    113         return nil;
    114     if (!self->_private->catchesDelegateExceptions)
    115         return reinterpret_cast<id (*)(id, SEL, WebView *, NSRect)>(objc_msgSend)(delegate, selector, self, rect);
    116     @try {
    117         return reinterpret_cast<id (*)(id, SEL, WebView *, NSRect)>(objc_msgSend)(delegate, selector, self, rect);
    118     } @catch(id exception) {
    119         ReportDiscardedDelegateException(selector, exception);
    120     }
    121     return nil;
    122 }
    123 
    124 static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object1, id object2)
    125 {
    126     if (!delegate || ![delegate respondsToSelector:selector])
    127         return nil;
    128     if (!self->_private->catchesDelegateExceptions)
    129         return objc_msgSend(delegate, selector, self, object1, object2);
    130     @try {
    131         return objc_msgSend(delegate, selector, self, object1, object2);
    132     } @catch(id exception) {
    133         ReportDiscardedDelegateException(selector, exception);
    134     }
    135     return nil;
    136 }
    137 
    138 static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object, BOOL boolean)
    139 {
    140     if (!delegate || ![delegate respondsToSelector:selector])
    141         return nil;
    142     if (!self->_private->catchesDelegateExceptions)
    143         return objc_msgSend(delegate, selector, self, object, boolean);
    144     @try {
    145         return objc_msgSend(delegate, selector, self, object, boolean);
    146     } @catch(id exception) {
    147         ReportDiscardedDelegateException(selector, exception);
    148     }
    149     return nil;
    150 }
    151 
    152 static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object1, id object2, id object3)
    153 {
    154     if (!delegate || ![delegate respondsToSelector:selector])
    155         return nil;
    156     if (!self->_private->catchesDelegateExceptions)
    157         return objc_msgSend(delegate, selector, self, object1, object2, object3);
    158     @try {
    159         return objc_msgSend(delegate, selector, self, object1, object2, object3);
    160     } @catch(id exception) {
    161         ReportDiscardedDelegateException(selector, exception);
    162     }
    163     return nil;
    164 }
    165 
    166 static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object, NSUInteger integer)
    167 {
    168     if (!delegate || ![delegate respondsToSelector:selector])
    169         return nil;
    170     if (!self->_private->catchesDelegateExceptions)
    171         return objc_msgSend(delegate, selector, self, object, integer);
    172     @try {
    173         return objc_msgSend(delegate, selector, self, object, integer);
    174     } @catch(id exception) {
    175         ReportDiscardedDelegateException(selector, exception);
    176     }
    177     return nil;
    178 }
    179 
    180 static inline float CallDelegateReturningFloat(WebView *self, id delegate, SEL selector)
    181 {
    182     if (!delegate || ![delegate respondsToSelector:selector])
    183         return 0.0f;
    184     if (!self->_private->catchesDelegateExceptions)
    185         return objc_msgSend_float_return(delegate, selector, self);
    186     @try {
    187         return objc_msgSend_float_return(delegate, selector, self);
    188     } @catch(id exception) {
    189         ReportDiscardedDelegateException(selector, exception);
    190     }
    191     return 0.0f;
    192 }
    193 
    194 static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector)
    195 {
    196     if (!delegate || ![delegate respondsToSelector:selector])
    197         return result;
    198     if (!self->_private->catchesDelegateExceptions)
    199         return reinterpret_cast<BOOL (*)(id, SEL, WebView *)>(objc_msgSend)(delegate, selector, self);
    200     @try {
    201         return reinterpret_cast<BOOL (*)(id, SEL, WebView *)>(objc_msgSend)(delegate, selector, self);
    202     } @catch(id exception) {
    203         ReportDiscardedDelegateException(selector, exception);
    204     }
    205     return result;
    206 }
    207 
    208 static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object)
    209 {
    210     if (!delegate || ![delegate respondsToSelector:selector])
    211         return result;
    212     if (!self->_private->catchesDelegateExceptions)
    213         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id)>(objc_msgSend)(delegate, selector, self, object);
    214     @try {
    215         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id)>(objc_msgSend)(delegate, selector, self, object);
    216     } @catch(id exception) {
    217         ReportDiscardedDelegateException(selector, exception);
    218     }
    219     return result;
    220 }
    221 
    222 static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object, BOOL boolean)
    223 {
    224     if (!delegate || ![delegate respondsToSelector:selector])
    225         return result;
    226     if (!self->_private->catchesDelegateExceptions)
    227         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, BOOL)>(objc_msgSend)(delegate, selector, self, object, boolean);
    228     @try {
    229         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, BOOL)>(objc_msgSend)(delegate, selector, self, object, boolean);
    230     } @catch(id exception) {
    231         ReportDiscardedDelegateException(selector, exception);
    232     }
    233     return result;
    234 }
    235 
    236 static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object, BOOL boolean, id object2)
    237 {
    238     if (!delegate || ![delegate respondsToSelector:selector])
    239         return result;
    240     if (!self->_private->catchesDelegateExceptions)
    241         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, BOOL, id)>(objc_msgSend)(delegate, selector, self, object, boolean, object2);
    242     @try {
    243         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, BOOL, id)>(objc_msgSend)(delegate, selector, self, object, boolean, object2);
    244     } @catch(id exception) {
    245         ReportDiscardedDelegateException(selector, exception);
    246     }
    247     return result;
    248 }
    249 
    250 static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object1, id object2)
    251 {
    252     if (!delegate || ![delegate respondsToSelector:selector])
    253         return result;
    254     if (!self->_private->catchesDelegateExceptions)
    255         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(delegate, selector, self, object1, object2);
    256     @try {
    257         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(delegate, selector, self, object1, object2);
    258     } @catch(id exception) {
    259         ReportDiscardedDelegateException(selector, exception);
    260     }
    261     return result;
    262 }
    263 
    264 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector)
    265 {
    266     if (!delegate)
    267         return nil;
    268     if (!self->_private->catchesDelegateExceptions)
    269         return implementation(delegate, selector, self);
    270     @try {
    271         return implementation(delegate, selector, self);
    272     } @catch(id exception) {
    273         ReportDiscardedDelegateException(selector, exception);
    274     }
    275     return nil;
    276 }
    277 
    278 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object)
    279 {
    280     if (!delegate)
    281         return nil;
    282     if (!self->_private->catchesDelegateExceptions)
    283         return implementation(delegate, selector, self, object);
    284     @try {
    285         return implementation(delegate, selector, self, object);
    286     } @catch(id exception) {
    287         ReportDiscardedDelegateException(selector, exception);
    288     }
    289     return nil;
    290 }
    291 
    292 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2)
    293 {
    294     if (!delegate)
    295         return nil;
    296     if (!self->_private->catchesDelegateExceptions)
    297         return implementation(delegate, selector, self, object1, object2);
    298     @try {
    299         return implementation(delegate, selector, self, object1, object2);
    300     } @catch(id exception) {
    301         ReportDiscardedDelegateException(selector, exception);
    302     }
    303     return nil;
    304 }
    305 
    306 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3)
    307 {
    308     if (!delegate)
    309         return nil;
    310     if (!self->_private->catchesDelegateExceptions)
    311         return implementation(delegate, selector, self, object1, object2, object3);
    312     @try {
    313         return implementation(delegate, selector, self, object1, object2, object3);
    314     } @catch(id exception) {
    315         ReportDiscardedDelegateException(selector, exception);
    316     }
    317     return nil;
    318 }
    319 
    320 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3, id object4)
    321 {
    322     if (!delegate)
    323         return nil;
    324     if (!self->_private->catchesDelegateExceptions)
    325         return implementation(delegate, selector, self, object1, object2, object3, object4);
    326     @try {
    327         return implementation(delegate, selector, self, object1, object2, object3, object4);
    328     } @catch(id exception) {
    329         ReportDiscardedDelegateException(selector, exception);
    330     }
    331     return nil;
    332 }
    333 
    334 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2)
    335 {
    336     if (!delegate)
    337         return nil;
    338     if (!self->_private->catchesDelegateExceptions)
    339         return implementation(delegate, selector, self, object1, integer, object2);
    340     @try {
    341         return implementation(delegate, selector, self, object1, integer, object2);
    342     } @catch(id exception) {
    343         ReportDiscardedDelegateException(selector, exception);
    344     }
    345     return nil;
    346 }
    347 
    348 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, int integer2, id object2)
    349 {
    350     if (!delegate)
    351         return nil;
    352     if (!self->_private->catchesDelegateExceptions)
    353         return implementation(delegate, selector, self, object1, integer1, integer2, object2);
    354     @try {
    355         return implementation(delegate, selector, self, object1, integer1, integer2, object2);
    356     } @catch(id exception) {
    357         ReportDiscardedDelegateException(selector, exception);
    358     }
    359     return nil;
    360 }
    361 
    362 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, BOOL boolean, NSInteger integer1, int integer2, id object2)
    363 {
    364     if (!delegate)
    365         return nil;
    366     if (!self->_private->catchesDelegateExceptions)
    367         return implementation(delegate, selector, self, object1, boolean, integer1, integer2, object2);
    368     @try {
    369         return implementation(delegate, selector, self, object1, boolean, integer1, integer2, object2);
    370     } @catch(id exception) {
    371         ReportDiscardedDelegateException(selector, exception);
    372     }
    373     return nil;
    374 }
    375 
    376 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, NSInteger integer, id object3)
    377 {
    378     if (!delegate)
    379         return nil;
    380     if (!self->_private->catchesDelegateExceptions)
    381         return implementation(delegate, selector, self, object1, object2, integer, object3);
    382     @try {
    383         return implementation(delegate, selector, self, object1, object2, integer, object3);
    384     } @catch(id exception) {
    385         ReportDiscardedDelegateException(selector, exception);
    386     }
    387     return nil;
    388 }
    389 
    390 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3)
    391 {
    392     if (!delegate)
    393         return nil;
    394     if (!self->_private->catchesDelegateExceptions)
    395         return implementation(delegate, selector, self, object1, integer1, object2, integer2, object3);
    396     @try {
    397         return implementation(delegate, selector, self, object1, integer1, object2, integer2, object3);
    398     } @catch(id exception) {
    399         ReportDiscardedDelegateException(selector, exception);
    400     }
    401     return nil;
    402 }
    403 
    404 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4)
    405 {
    406     if (!delegate)
    407         return nil;
    408     if (!self->_private->catchesDelegateExceptions)
    409         return implementation(delegate, selector, self, object1, integer, object2, object3, object4);
    410     @try {
    411         return implementation(delegate, selector, self, object1, integer, object2, object3, object4);
    412     } @catch(id exception) {
    413         ReportDiscardedDelegateException(selector, exception);
    414     }
    415     return nil;
    416 }
    417 
    418 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSTimeInterval interval, id object2, id object3)
    419 {
    420     if (!delegate)
    421         return nil;
    422     if (!self->_private->catchesDelegateExceptions)
    423         return implementation(delegate, selector, self, object1, interval, object2, object3);
    424     @try {
    425         return implementation(delegate, selector, self, object1, interval, object2, object3);
    426     } @catch(id exception) {
    427         ReportDiscardedDelegateException(selector, exception);
    428     }
    429     return nil;
    430 }
    431 
    432 id CallUIDelegate(WebView *self, SEL selector)
    433 {
    434     return CallDelegate(self, self->_private->UIDelegate, selector);
    435 }
    436 
    437 id CallUIDelegate(WebView *self, SEL selector, id object)
    438 {
    439     return CallDelegate(self, self->_private->UIDelegate, selector, object);
    440 }
    441 
    442 id CallUIDelegate(WebView *self, SEL selector, id object, BOOL boolean)
    443 {
    444     return CallDelegate(self, self->_private->UIDelegate, selector, object, boolean);
    445 }
    446 
    447 id CallUIDelegate(WebView *self, SEL selector, NSRect rect)
    448 {
    449     return CallDelegate(self, self->_private->UIDelegate, selector, rect);
    450 }
    451 
    452 id CallUIDelegate(WebView *self, SEL selector, id object1, id object2)
    453 {
    454     return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2);
    455 }
    456 
    457 id CallUIDelegate(WebView *self, SEL selector, id object1, id object2, id object3)
    458 {
    459     return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2, object3);
    460 }
    461 
    462 id CallUIDelegate(WebView *self, SEL selector, id object, NSUInteger integer)
    463 {
    464     return CallDelegate(self, self->_private->UIDelegate, selector, object, integer);
    465 }
    466 
    467 float CallUIDelegateReturningFloat(WebView *self, SEL selector)
    468 {
    469     return CallDelegateReturningFloat(self, self->_private->UIDelegate, selector);
    470 }
    471 
    472 BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector)
    473 {
    474     return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector);
    475 }
    476 
    477 BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object)
    478 {
    479     return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object);
    480 }
    481 
    482 BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object, BOOL boolean)
    483 {
    484     return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object, boolean);
    485 }
    486 
    487 BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object, BOOL boolean, id object2)
    488 {
    489     return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object, boolean, object2);
    490 }
    491 
    492 BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, id object2)
    493 {
    494     return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object1, object2);
    495 }
    496 
    497 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector)
    498 {
    499     return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector);
    500 }
    501 
    502 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object)
    503 {
    504     return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object);
    505 }
    506 
    507 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
    508 {
    509     return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2);
    510 }
    511 
    512 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
    513 {
    514     return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3);
    515 }
    516 
    517 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4)
    518 {
    519     return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3, object4);
    520 }
    521 
    522 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSTimeInterval interval, id object2, id object3)
    523 {
    524     return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, interval, object2, object3);
    525 }
    526 
    527 id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
    528 {
    529     return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2);
    530 }
    531 
    532 id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
    533 {
    534     return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3);
    535 }
    536 
    537 id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4)
    538 {
    539     return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3, object4);
    540 }
    541 
    542 id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2)
    543 {
    544     return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, integer, object2);
    545 }
    546 
    547 id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3)
    548 {
    549     return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, integer, object3);
    550 }
    551 
    552 BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector, id object1)
    553 {
    554     if (!self->_private->catchesDelegateExceptions)
    555         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1);
    556     @try {
    557         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1);
    558     } @catch(id exception) {
    559         ReportDiscardedDelegateException(selector, exception);
    560     }
    561     return result;
    562 }
    563 
    564 BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector, id object1, id object2)
    565 {
    566     if (!self->_private->catchesDelegateExceptions)
    567         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1, object2);
    568     @try {
    569         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1, object2);
    570     } @catch(id exception) {
    571         ReportDiscardedDelegateException(selector, exception);
    572     }
    573     return result;
    574 }
    575 
    576 BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
    577 {
    578     if (!self->_private->catchesDelegateExceptions)
    579         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1, object2, object3);
    580     @try {
    581         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1, object2, object3);
    582     } @catch(id exception) {
    583         ReportDiscardedDelegateException(selector, exception);
    584     }
    585     return result;
    586 }
    587 
    588 id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3)
    589 {
    590     return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, object2, integer, object3);
    591 }
    592 
    593 id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3)
    594 {
    595     return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, object2, integer2, object3);
    596 }
    597 
    598 id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4)
    599 {
    600     return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer, object2, object3, object4);
    601 }
    602 
    603 id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, int integer2, id object2)
    604 {
    605     return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, integer2, object2);
    606 }
    607 
    608 id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, BOOL boolean, NSInteger integer1, int integer2, id object2)
    609 {
    610     return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, boolean, integer1, integer2, object2);
    611 }
    612 
    613 id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector)
    614 {
    615     return CallDelegate(implementation, self, self->_private->historyDelegate, selector);
    616 }
    617 
    618 id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
    619 {
    620     return CallDelegate(implementation, self, self->_private->historyDelegate, selector, object1, object2);
    621 }
    622 
    623 id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
    624 {
    625     return CallDelegate(implementation, self, self->_private->historyDelegate, selector, object1, object2, object3);
    626 }
    627 
    628 // The form delegate needs to have it's own implementation, because the first argument is never the WebView
    629 
    630 id CallFormDelegate(WebView *self, SEL selector, id object1, id object2)
    631 {
    632     id delegate = self->_private->formDelegate;
    633     if (!delegate || ![delegate respondsToSelector:selector])
    634         return nil;
    635     if (!self->_private->catchesDelegateExceptions)
    636         return objc_msgSend(delegate, selector, object1, object2);
    637     @try {
    638         return objc_msgSend(delegate, selector, object1, object2);
    639     } @catch(id exception) {
    640         ReportDiscardedDelegateException(selector, exception);
    641     }
    642     return nil;
    643 }
    644 
    645 id CallFormDelegate(WebView *self, SEL selector, id object1, id object2, id object3, id object4, id object5)
    646 {
    647     id delegate = self->_private->formDelegate;
    648     if (!delegate || ![delegate respondsToSelector:selector])
    649         return nil;
    650     if (!self->_private->catchesDelegateExceptions)
    651         return objc_msgSend(delegate, selector, object1, object2, object3, object4, object5);
    652     @try {
    653         return objc_msgSend(delegate, selector, object1, object2, object3, object4, object5);
    654     } @catch(id exception) {
    655         ReportDiscardedDelegateException(selector, exception);
    656     }
    657     return nil;
    658 }
    659 
    660 BOOL CallFormDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, SEL selectorArg, id object2)
    661 {
    662     id delegate = self->_private->formDelegate;
    663     if (!delegate || ![delegate respondsToSelector:selector])
    664         return result;
    665     if (!self->_private->catchesDelegateExceptions)
    666         return reinterpret_cast<BOOL (*)(id, SEL, id, SEL, id)>(objc_msgSend)(delegate, selector, object1, selectorArg, object2);
    667     @try {
    668         return reinterpret_cast<BOOL (*)(id, SEL, id, SEL, id)>(objc_msgSend)(delegate, selector, object1, selectorArg, object2);
    669     } @catch(id exception) {
    670         ReportDiscardedDelegateException(selector, exception);
    671     }
    672     return result;
    673 }
    674 
    675 @end
    676