1/* 2 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2006 David Smith (catfish.man@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 39WebResourceDelegateImplementationCache* WebViewGetResourceLoadDelegateImplementations(WebView *webView) 40{ 41 static WebResourceDelegateImplementationCache empty; 42 if (!webView) 43 return ∅ 44 return &webView->_private->resourceLoadDelegateImplementations; 45} 46 47WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementations(WebView *webView) 48{ 49 static WebFrameLoadDelegateImplementationCache empty; 50 if (!webView) 51 return ∅ 52 return &webView->_private->frameLoadDelegateImplementations; 53} 54 55WebScriptDebugDelegateImplementationCache* WebViewGetScriptDebugDelegateImplementations(WebView *webView) 56{ 57 static WebScriptDebugDelegateImplementationCache empty; 58 if (!webView) 59 return ∅ 60 return &webView->_private->scriptDebugDelegateImplementations; 61} 62 63WebHistoryDelegateImplementationCache* WebViewGetHistoryDelegateImplementations(WebView *webView) 64{ 65 static WebHistoryDelegateImplementationCache empty; 66 if (!webView) 67 return ∅ 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 75typedef float (*ObjCMsgSendFPRet)(id, SEL, ...); 76#if defined(__i386__) 77static const ObjCMsgSendFPRet objc_msgSend_float_return = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend_fpret); 78#else 79static const ObjCMsgSendFPRet objc_msgSend_float_return = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend); 80#endif 81 82static 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 96static 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 110static 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 124static 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 138static 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 152static 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 166static 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 180static 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 194static 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 208static 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 222static 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 236static 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 250static 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 264static 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 278static 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 292static 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 306static 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 320static 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 334static 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 348static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, NSInteger 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 362static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, NSInteger integer, id object3) 363{ 364 if (!delegate) 365 return nil; 366 if (!self->_private->catchesDelegateExceptions) 367 return implementation(delegate, selector, self, object1, object2, integer, object3); 368 @try { 369 return implementation(delegate, selector, self, object1, object2, integer, object3); 370 } @catch(id exception) { 371 ReportDiscardedDelegateException(selector, exception); 372 } 373 return nil; 374} 375 376static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3) 377{ 378 if (!delegate) 379 return nil; 380 if (!self->_private->catchesDelegateExceptions) 381 return implementation(delegate, selector, self, object1, integer1, object2, integer2, object3); 382 @try { 383 return implementation(delegate, selector, self, object1, integer1, object2, integer2, object3); 384 } @catch(id exception) { 385 ReportDiscardedDelegateException(selector, exception); 386 } 387 return nil; 388} 389 390static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4) 391{ 392 if (!delegate) 393 return nil; 394 if (!self->_private->catchesDelegateExceptions) 395 return implementation(delegate, selector, self, object1, integer, object2, object3, object4); 396 @try { 397 return implementation(delegate, selector, self, object1, integer, object2, object3, object4); 398 } @catch(id exception) { 399 ReportDiscardedDelegateException(selector, exception); 400 } 401 return nil; 402} 403 404static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSTimeInterval interval, id object2, id object3) 405{ 406 if (!delegate) 407 return nil; 408 if (!self->_private->catchesDelegateExceptions) 409 return implementation(delegate, selector, self, object1, interval, object2, object3); 410 @try { 411 return implementation(delegate, selector, self, object1, interval, object2, object3); 412 } @catch(id exception) { 413 ReportDiscardedDelegateException(selector, exception); 414 } 415 return nil; 416} 417 418id CallUIDelegate(WebView *self, SEL selector) 419{ 420 return CallDelegate(self, self->_private->UIDelegate, selector); 421} 422 423id CallUIDelegate(WebView *self, SEL selector, id object) 424{ 425 return CallDelegate(self, self->_private->UIDelegate, selector, object); 426} 427 428id CallUIDelegate(WebView *self, SEL selector, id object, BOOL boolean) 429{ 430 return CallDelegate(self, self->_private->UIDelegate, selector, object, boolean); 431} 432 433id CallUIDelegate(WebView *self, SEL selector, NSRect rect) 434{ 435 return CallDelegate(self, self->_private->UIDelegate, selector, rect); 436} 437 438id CallUIDelegate(WebView *self, SEL selector, id object1, id object2) 439{ 440 return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2); 441} 442 443id CallUIDelegate(WebView *self, SEL selector, id object1, id object2, id object3) 444{ 445 return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2, object3); 446} 447 448id CallUIDelegate(WebView *self, SEL selector, id object, NSUInteger integer) 449{ 450 return CallDelegate(self, self->_private->UIDelegate, selector, object, integer); 451} 452 453float CallUIDelegateReturningFloat(WebView *self, SEL selector) 454{ 455 return CallDelegateReturningFloat(self, self->_private->UIDelegate, selector); 456} 457 458BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector) 459{ 460 return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector); 461} 462 463BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object) 464{ 465 return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object); 466} 467 468BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object, BOOL boolean) 469{ 470 return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object, boolean); 471} 472 473BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object, BOOL boolean, id object2) 474{ 475 return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object, boolean, object2); 476} 477 478BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, id object2) 479{ 480 return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object1, object2); 481} 482 483id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector) 484{ 485 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector); 486} 487 488id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object) 489{ 490 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object); 491} 492 493id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2) 494{ 495 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2); 496} 497 498id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3) 499{ 500 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3); 501} 502 503id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4) 504{ 505 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3, object4); 506} 507 508id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSTimeInterval interval, id object2, id object3) 509{ 510 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, interval, object2, object3); 511} 512 513id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2) 514{ 515 return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2); 516} 517 518id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3) 519{ 520 return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3); 521} 522 523id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4) 524{ 525 return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3, object4); 526} 527 528id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2) 529{ 530 return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, integer, object2); 531} 532 533id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3) 534{ 535 return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, integer, object3); 536} 537 538BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector, id object1, id object2) 539{ 540 if (!self->_private->catchesDelegateExceptions) 541 return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1, object2); 542 @try { 543 return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1, object2); 544 } @catch(id exception) { 545 ReportDiscardedDelegateException(selector, exception); 546 } 547 return result; 548} 549 550id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3) 551{ 552 return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, object2, integer, object3); 553} 554 555id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3) 556{ 557 return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, object2, integer2, object3); 558} 559 560id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4) 561{ 562 return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer, object2, object3, object4); 563} 564 565id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, NSInteger integer2, id object2) 566{ 567 return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, integer2, object2); 568} 569 570id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector) 571{ 572 return CallDelegate(implementation, self, self->_private->historyDelegate, selector); 573} 574 575id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2) 576{ 577 return CallDelegate(implementation, self, self->_private->historyDelegate, selector, object1, object2); 578} 579 580id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3) 581{ 582 return CallDelegate(implementation, self, self->_private->historyDelegate, selector, object1, object2, object3); 583} 584 585// The form delegate needs to have it's own implementation, because the first argument is never the WebView 586 587id CallFormDelegate(WebView *self, SEL selector, id object1, id object2) 588{ 589 id delegate = self->_private->formDelegate; 590 if (!delegate || ![delegate respondsToSelector:selector]) 591 return nil; 592 if (!self->_private->catchesDelegateExceptions) 593 return objc_msgSend(delegate, selector, object1, object2); 594 @try { 595 return objc_msgSend(delegate, selector, object1, object2); 596 } @catch(id exception) { 597 ReportDiscardedDelegateException(selector, exception); 598 } 599 return nil; 600} 601 602id CallFormDelegate(WebView *self, SEL selector, id object1, id object2, id object3, id object4, id object5) 603{ 604 id delegate = self->_private->formDelegate; 605 if (!delegate || ![delegate respondsToSelector:selector]) 606 return nil; 607 if (!self->_private->catchesDelegateExceptions) 608 return objc_msgSend(delegate, selector, object1, object2, object3, object4, object5); 609 @try { 610 return objc_msgSend(delegate, selector, object1, object2, object3, object4, object5); 611 } @catch(id exception) { 612 ReportDiscardedDelegateException(selector, exception); 613 } 614 return nil; 615} 616 617BOOL CallFormDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, SEL selectorArg, id object2) 618{ 619 id delegate = self->_private->formDelegate; 620 if (!delegate || ![delegate respondsToSelector:selector]) 621 return result; 622 if (!self->_private->catchesDelegateExceptions) 623 return reinterpret_cast<BOOL (*)(id, SEL, id, SEL, id)>(objc_msgSend)(delegate, selector, object1, selectorArg, object2); 624 @try { 625 return reinterpret_cast<BOOL (*)(id, SEL, id, SEL, id)>(objc_msgSend)(delegate, selector, object1, selectorArg, object2); 626 } @catch(id exception) { 627 ReportDiscardedDelegateException(selector, exception); 628 } 629 return result; 630} 631 632@end 633