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 ∅ 44 return &webView->_private->resourceLoadDelegateImplementations; 45 } 46 47 WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementations(WebView *webView) 48 { 49 static WebFrameLoadDelegateImplementationCache empty; 50 if (!webView) 51 return ∅ 52 return &webView->_private->frameLoadDelegateImplementations; 53 } 54 55 WebScriptDebugDelegateImplementationCache* WebViewGetScriptDebugDelegateImplementations(WebView *webView) 56 { 57 static WebScriptDebugDelegateImplementationCache empty; 58 if (!webView) 59 return ∅ 60 return &webView->_private->scriptDebugDelegateImplementations; 61 } 62 63 WebHistoryDelegateImplementationCache* 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 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, 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 362 static 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 376 static 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 390 static 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 404 static 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 418 id CallUIDelegate(WebView *self, SEL selector) 419 { 420 return CallDelegate(self, self->_private->UIDelegate, selector); 421 } 422 423 id CallUIDelegate(WebView *self, SEL selector, id object) 424 { 425 return CallDelegate(self, self->_private->UIDelegate, selector, object); 426 } 427 428 id CallUIDelegate(WebView *self, SEL selector, id object, BOOL boolean) 429 { 430 return CallDelegate(self, self->_private->UIDelegate, selector, object, boolean); 431 } 432 433 id CallUIDelegate(WebView *self, SEL selector, NSRect rect) 434 { 435 return CallDelegate(self, self->_private->UIDelegate, selector, rect); 436 } 437 438 id CallUIDelegate(WebView *self, SEL selector, id object1, id object2) 439 { 440 return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2); 441 } 442 443 id 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 448 id CallUIDelegate(WebView *self, SEL selector, id object, NSUInteger integer) 449 { 450 return CallDelegate(self, self->_private->UIDelegate, selector, object, integer); 451 } 452 453 float CallUIDelegateReturningFloat(WebView *self, SEL selector) 454 { 455 return CallDelegateReturningFloat(self, self->_private->UIDelegate, selector); 456 } 457 458 BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector) 459 { 460 return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector); 461 } 462 463 BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object) 464 { 465 return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object); 466 } 467 468 BOOL 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 473 BOOL 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 478 BOOL 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 483 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector) 484 { 485 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector); 486 } 487 488 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object) 489 { 490 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object); 491 } 492 493 id 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 498 id 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 503 id 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 508 id 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 513 id 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 518 id 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 523 id 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 528 id 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 533 id 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 538 BOOL 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 550 id 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 555 id 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 560 id 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 565 id 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 570 id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector) 571 { 572 return CallDelegate(implementation, self, self->_private->historyDelegate, selector); 573 } 574 575 id 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 580 id 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 587 id 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 602 id 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 617 BOOL 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