1 /* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #import "BrowserWindowController.h" 27 28 #import <WebKit2/WKPagePrivate.h> 29 #import <WebKit2/WKStringCF.h> 30 #import <WebKit2/WKURLCF.h> 31 32 @interface BrowserWindowController () 33 - (void)didStartProgress; 34 - (void)didChangeProgress:(double)value; 35 - (void)didFinishProgress; 36 - (void)didStartProvisionalLoadForFrame:(WKFrameRef)frame; 37 - (void)didCommitLoadForFrame:(WKFrameRef)frame; 38 - (void)didReceiveServerRedirectForProvisionalLoadForFrame:(WKFrameRef)frame; 39 - (void)didFailProvisionalLoadWithErrorForFrame:(WKFrameRef)frame; 40 - (void)didFailLoadWithErrorForFrame:(WKFrameRef)frame; 41 - (void)didSameDocumentNavigationForFrame:(WKFrameRef)frame; 42 @end 43 44 @implementation BrowserWindowController 45 46 - (id)initWithContext:(WKContextRef)context 47 { 48 if ((self = [super initWithWindowNibName:@"BrowserWindow"])) { 49 _context = WKRetain(context); 50 _zoomTextOnly = NO; 51 } 52 53 return self; 54 } 55 56 - (void)dealloc 57 { 58 assert(!_context); 59 [super dealloc]; 60 } 61 62 - (IBAction)fetch:(id)sender 63 { 64 CFURLRef cfURL = CFURLCreateWithString(0, (CFStringRef)[urlText stringValue], 0); 65 if (!cfURL) 66 return; 67 68 WKURLRef url = WKURLCreateWithCFURL(cfURL); 69 CFRelease(cfURL); 70 71 WKPageLoadURL(_webView.pageRef, url); 72 WKRelease(url); 73 } 74 75 - (IBAction)showHideWebView:(id)sender 76 { 77 BOOL hidden = ![_webView isHidden]; 78 79 [_webView setHidden:hidden]; 80 } 81 82 - (IBAction)removeReinsertWebView:(id)sender 83 { 84 if ([_webView window]) { 85 [_webView retain]; 86 [_webView removeFromSuperview]; 87 } else { 88 [containerView addSubview:_webView]; 89 [_webView release]; 90 } 91 } 92 93 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem 94 { 95 SEL action = [menuItem action]; 96 97 if (action == @selector(zoomIn:)) 98 return [self canZoomIn]; 99 if (action == @selector(zoomOut:)) 100 return [self canZoomOut]; 101 if (action == @selector(resetZoom:)) 102 return [self canResetZoom]; 103 104 if (action == @selector(showHideWebView:)) 105 [menuItem setTitle:[_webView isHidden] ? @"Show Web View" : @"Hide Web View"]; 106 else if (action == @selector(removeReinsertWebView:)) 107 [menuItem setTitle:[_webView window] ? @"Remove Web View" : @"Insert Web View"]; 108 else if (action == @selector(toggleZoomMode:)) 109 [menuItem setState:_zoomTextOnly ? NSOnState : NSOffState]; 110 return YES; 111 } 112 113 - (IBAction)reload:(id)sender 114 { 115 WKPageReload(_webView.pageRef); 116 } 117 118 - (IBAction)forceRepaint:(id)sender 119 { 120 [_webView setNeedsDisplay:YES]; 121 } 122 123 - (IBAction)goBack:(id)sender 124 { 125 WKPageGoBack(_webView.pageRef); 126 } 127 128 - (IBAction)goForward:(id)sender 129 { 130 WKPageGoForward(_webView.pageRef); 131 } 132 133 - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item 134 { 135 SEL action = [item action]; 136 137 if (action == @selector(goBack:)) 138 return _webView && WKPageCanGoBack(_webView.pageRef); 139 140 if (action == @selector(goForward:)) 141 return _webView && WKPageCanGoForward(_webView.pageRef); 142 143 return YES; 144 } 145 146 - (void)validateToolbar 147 { 148 [toolbar validateVisibleItems]; 149 } 150 151 - (BOOL)windowShouldClose:(id)sender 152 { 153 LOG(@"windowShouldClose"); 154 BOOL canCloseImmediately = WKPageTryClose(_webView.pageRef); 155 return canCloseImmediately; 156 } 157 158 - (void)windowWillClose:(NSNotification *)notification 159 { 160 WKRelease(_context); 161 _context = 0; 162 } 163 164 - (void)applicationTerminating 165 { 166 WKPageClose(_webView.pageRef); 167 WKRelease(_webView.pageRef); 168 } 169 170 #define DefaultMinimumZoomFactor (.5) 171 #define DefaultMaximumZoomFactor (3.0) 172 #define DefaultZoomFactorRatio (1.2) 173 174 - (double)currentZoomFactor 175 { 176 return _zoomTextOnly ? WKPageGetTextZoomFactor(_webView.pageRef) : WKPageGetPageZoomFactor(_webView.pageRef); 177 } 178 179 - (void)setCurrentZoomFactor:(double)factor 180 { 181 _zoomTextOnly ? WKPageSetTextZoomFactor(_webView.pageRef, factor) : WKPageSetPageZoomFactor(_webView.pageRef, factor); 182 } 183 184 - (BOOL)canZoomIn 185 { 186 return [self currentZoomFactor] * DefaultZoomFactorRatio < DefaultMaximumZoomFactor; 187 } 188 189 - (void)zoomIn:(id)sender 190 { 191 if (![self canZoomIn]) 192 return; 193 194 double factor = [self currentZoomFactor] * DefaultZoomFactorRatio; 195 [self setCurrentZoomFactor:factor]; 196 } 197 198 - (BOOL)canZoomOut 199 { 200 return [self currentZoomFactor] / DefaultZoomFactorRatio > DefaultMinimumZoomFactor; 201 } 202 203 - (void)zoomOut:(id)sender 204 { 205 if (![self canZoomIn]) 206 return; 207 208 double factor = [self currentZoomFactor] / DefaultZoomFactorRatio; 209 [self setCurrentZoomFactor:factor]; 210 } 211 212 - (BOOL)canResetZoom 213 { 214 return _zoomTextOnly ? (WKPageGetTextZoomFactor(_webView.pageRef) != 1) : (WKPageGetPageZoomFactor(_webView.pageRef) != 1); 215 } 216 217 - (void)resetZoom:(id)sender 218 { 219 if (![self canResetZoom]) 220 return; 221 222 if (_zoomTextOnly) 223 WKPageSetTextZoomFactor(_webView.pageRef, 1); 224 else 225 WKPageSetPageZoomFactor(_webView.pageRef, 1); 226 } 227 228 - (IBAction)toggleZoomMode:(id)sender 229 { 230 if (_zoomTextOnly) { 231 _zoomTextOnly = NO; 232 double currentTextZoom = WKPageGetTextZoomFactor(_webView.pageRef); 233 WKPageSetPageAndTextZoomFactors(_webView.pageRef, currentTextZoom, 1); 234 } else { 235 _zoomTextOnly = YES; 236 double currentPageZoom = WKPageGetPageZoomFactor(_webView.pageRef); 237 WKPageSetPageAndTextZoomFactors(_webView.pageRef, 1, currentPageZoom); 238 } 239 } 240 241 - (IBAction)dumpSourceToConsole:(id)sender 242 { 243 WKPageGetSourceForFrame_b(_webView.pageRef, WKPageGetMainFrame(_webView.pageRef), ^(WKStringRef result, WKErrorRef error) { 244 CFStringRef cfResult = WKStringCopyCFString(0, result); 245 LOG(@"Main frame source\n \"%@\"", (NSString *)cfResult); 246 CFRelease(cfResult); 247 }); 248 } 249 250 // MARK: Loader Client Callbacks 251 252 static void didStartProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 253 { 254 [(BrowserWindowController *)clientInfo didStartProvisionalLoadForFrame:frame]; 255 } 256 257 static void didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 258 { 259 [(BrowserWindowController *)clientInfo didReceiveServerRedirectForProvisionalLoadForFrame:frame]; 260 } 261 262 static void didFailProvisionalLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, WKErrorRef error, WKTypeRef userData, const void *clientInfo) 263 { 264 [(BrowserWindowController *)clientInfo didFailProvisionalLoadWithErrorForFrame:frame]; 265 } 266 267 static void didCommitLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 268 { 269 [(BrowserWindowController *)clientInfo didCommitLoadForFrame:frame]; 270 } 271 272 static void didFinishDocumentLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 273 { 274 LOG(@"didFinishDocumentLoadForFrame"); 275 } 276 277 static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 278 { 279 LOG(@"didFinishLoadForFrame"); 280 } 281 282 static void didFailLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, WKErrorRef error, WKTypeRef userData, const void *clientInfo) 283 { 284 [(BrowserWindowController *)clientInfo didFailLoadWithErrorForFrame:frame]; 285 } 286 287 static void didSameDocumentNavigationForFrame(WKPageRef page, WKFrameRef frame, WKSameDocumentNavigationType type, WKTypeRef userData, const void *clientInfo) 288 { 289 [(BrowserWindowController *)clientInfo didSameDocumentNavigationForFrame:frame]; 290 } 291 292 static void didReceiveTitleForFrame(WKPageRef page, WKStringRef title, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 293 { 294 CFStringRef cfTitle = WKStringCopyCFString(0, title); 295 LOG(@"didReceiveTitleForFrame \"%@\"", (NSString *)cfTitle); 296 CFRelease(cfTitle); 297 } 298 299 static void didFirstLayoutForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 300 { 301 LOG(@"didFirstLayoutForFrame"); 302 } 303 304 static void didFirstVisuallyNonEmptyLayoutForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 305 { 306 LOG(@"didFirstVisuallyNonEmptyLayoutForFrame"); 307 } 308 309 static void didRemoveFrameFromHierarchy(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 310 { 311 LOG(@"didRemoveFrameFromHierarchy"); 312 } 313 314 static void didDisplayInsecureContentForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 315 { 316 LOG(@"didDisplayInsecureContentForFrame"); 317 } 318 319 static void didRunInsecureContentForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 320 { 321 LOG(@"didRunInsecureContentForFrame"); 322 } 323 324 static void didStartProgress(WKPageRef page, const void *clientInfo) 325 { 326 [(BrowserWindowController *)clientInfo didStartProgress]; 327 } 328 329 static void didChangeProgress(WKPageRef page, const void *clientInfo) 330 { 331 [(BrowserWindowController *)clientInfo didChangeProgress:WKPageGetEstimatedProgress(page)]; 332 } 333 334 static void didFinishProgress(WKPageRef page, const void *clientInfo) 335 { 336 [(BrowserWindowController *)clientInfo didFinishProgress]; 337 } 338 339 static void didBecomeUnresponsive(WKPageRef page, const void *clientInfo) 340 { 341 LOG(@"didBecomeUnresponsive"); 342 } 343 344 static void didBecomeResponsive(WKPageRef page, const void *clientInfo) 345 { 346 LOG(@"didBecomeResponsive"); 347 } 348 349 static void processDidExit(WKPageRef page, const void *clientInfo) 350 { 351 LOG(@"processDidExit"); 352 } 353 354 static void didChangeBackForwardList(WKPageRef page, WKBackForwardListItemRef addedItem, WKArrayRef removedItems, const void *clientInfo) 355 { 356 [(BrowserWindowController *)clientInfo validateToolbar]; 357 } 358 359 // MARK: Policy Client Callbacks 360 361 static void decidePolicyForNavigationAction(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) 362 { 363 LOG(@"decidePolicyForNavigationAction"); 364 WKFramePolicyListenerUse(listener); 365 } 366 367 static void decidePolicyForNewWindowAction(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKStringRef frameName, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) 368 { 369 LOG(@"decidePolicyForNewWindowAction"); 370 WKFramePolicyListenerUse(listener); 371 } 372 373 static void decidePolicyForResponse(WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) 374 { 375 WKFramePolicyListenerUse(listener); 376 } 377 378 // MARK: UI Client Callbacks 379 380 static WKPageRef createNewPage(WKPageRef page, WKDictionaryRef features, WKEventModifiers modifiers, WKEventMouseButton button, const void* clientInfo) 381 { 382 LOG(@"createNewPage"); 383 BrowserWindowController *controller = [[BrowserWindowController alloc] initWithContext:WKPageGetContext(page)]; 384 [controller loadWindow]; 385 386 return controller->_webView.pageRef; 387 } 388 389 static void showPage(WKPageRef page, const void *clientInfo) 390 { 391 LOG(@"showPage"); 392 [[(BrowserWindowController *)clientInfo window] orderFront:nil]; 393 } 394 395 static void closePage(WKPageRef page, const void *clientInfo) 396 { 397 LOG(@"closePage"); 398 WKPageClose(page); 399 [[(BrowserWindowController *)clientInfo window] close]; 400 WKRelease(page); 401 } 402 403 static void runJavaScriptAlert(WKPageRef page, WKStringRef message, WKFrameRef frame, const void* clientInfo) 404 { 405 NSAlert* alert = [[NSAlert alloc] init]; 406 407 WKURLRef wkURL = WKFrameCopyURL(frame); 408 CFURLRef cfURL = WKURLCopyCFURL(0, wkURL); 409 WKRelease(wkURL); 410 411 [alert setMessageText:[NSString stringWithFormat:@"JavaScript alert dialog from %@.", [(NSURL *)cfURL absoluteString]]]; 412 CFRelease(cfURL); 413 414 CFStringRef cfMessage = WKStringCopyCFString(0, message); 415 [alert setInformativeText:(NSString *)cfMessage]; 416 CFRelease(cfMessage); 417 418 [alert addButtonWithTitle:@"OK"]; 419 420 [alert runModal]; 421 [alert release]; 422 } 423 424 static bool runJavaScriptConfirm(WKPageRef page, WKStringRef message, WKFrameRef frame, const void* clientInfo) 425 { 426 NSAlert* alert = [[NSAlert alloc] init]; 427 428 WKURLRef wkURL = WKFrameCopyURL(frame); 429 CFURLRef cfURL = WKURLCopyCFURL(0, wkURL); 430 WKRelease(wkURL); 431 432 [alert setMessageText:[NSString stringWithFormat:@"JavaScript confirm dialog from %@.", [(NSURL *)cfURL absoluteString]]]; 433 CFRelease(cfURL); 434 435 CFStringRef cfMessage = WKStringCopyCFString(0, message); 436 [alert setInformativeText:(NSString *)cfMessage]; 437 CFRelease(cfMessage); 438 439 [alert addButtonWithTitle:@"OK"]; 440 [alert addButtonWithTitle:@"Cancel"]; 441 442 NSInteger button = [alert runModal]; 443 [alert release]; 444 445 return button == NSAlertFirstButtonReturn; 446 } 447 448 static WKStringRef runJavaScriptPrompt(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, const void* clientInfo) 449 { 450 NSAlert* alert = [[NSAlert alloc] init]; 451 452 WKURLRef wkURL = WKFrameCopyURL(frame); 453 CFURLRef cfURL = WKURLCopyCFURL(0, wkURL); 454 WKRelease(wkURL); 455 456 [alert setMessageText:[NSString stringWithFormat:@"JavaScript prompt dialog from %@.", [(NSURL *)cfURL absoluteString]]]; 457 CFRelease(cfURL); 458 459 CFStringRef cfMessage = WKStringCopyCFString(0, message); 460 [alert setInformativeText:(NSString *)cfMessage]; 461 CFRelease(cfMessage); 462 463 [alert addButtonWithTitle:@"OK"]; 464 [alert addButtonWithTitle:@"Cancel"]; 465 466 NSTextField* input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)]; 467 CFStringRef cfDefaultValue = WKStringCopyCFString(0, defaultValue); 468 [input setStringValue:(NSString *)cfDefaultValue]; 469 CFRelease(cfDefaultValue); 470 471 [alert setAccessoryView:input]; 472 473 NSInteger button = [alert runModal]; 474 475 NSString* result = nil; 476 if (button == NSAlertFirstButtonReturn) { 477 [input validateEditing]; 478 result = [input stringValue]; 479 } 480 481 [alert release]; 482 483 if (!result) 484 return 0; 485 return WKStringCreateWithCFString((CFStringRef)result); 486 } 487 488 static void setStatusText(WKPageRef page, WKStringRef text, const void* clientInfo) 489 { 490 LOG(@"setStatusText"); 491 } 492 493 static void mouseDidMoveOverElement(WKPageRef page, WKEventModifiers modifiers, WKTypeRef userData, const void *clientInfo) 494 { 495 LOG(@"mouseDidMoveOverElement"); 496 } 497 498 static WKRect getWindowFrame(WKPageRef page, const void* clientInfo) 499 { 500 NSRect rect = [[(BrowserWindowController *)clientInfo window] frame]; 501 WKRect wkRect; 502 wkRect.origin.x = rect.origin.x; 503 wkRect.origin.y = rect.origin.y; 504 wkRect.size.width = rect.size.width; 505 wkRect.size.height = rect.size.height; 506 return wkRect; 507 } 508 509 static void setWindowFrame(WKPageRef page, WKRect rect, const void* clientInfo) 510 { 511 [[(BrowserWindowController *)clientInfo window] setFrame:NSMakeRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height) display:YES]; 512 } 513 514 static bool runBeforeUnloadConfirmPanel(WKPageRef page, WKStringRef message, WKFrameRef frame, const void* clientInfo) 515 { 516 NSAlert *alert = [[NSAlert alloc] init]; 517 518 WKURLRef wkURL = WKFrameCopyURL(frame); 519 CFURLRef cfURL = WKURLCopyCFURL(0, wkURL); 520 WKRelease(wkURL); 521 522 [alert setMessageText:[NSString stringWithFormat:@"BeforeUnload confirm dialog from %@.", [(NSURL *)cfURL absoluteString]]]; 523 CFRelease(cfURL); 524 525 CFStringRef cfMessage = WKStringCopyCFString(0, message); 526 [alert setInformativeText:(NSString *)cfMessage]; 527 CFRelease(cfMessage); 528 529 [alert addButtonWithTitle:@"OK"]; 530 [alert addButtonWithTitle:@"Cancel"]; 531 532 NSInteger button = [alert runModal]; 533 [alert release]; 534 535 return button == NSAlertFirstButtonReturn; 536 } 537 538 static void runOpenPanel(WKPageRef page, WKFrameRef frame, WKOpenPanelParametersRef parameters, WKOpenPanelResultListenerRef listener, const void* clientInfo) 539 { 540 NSOpenPanel *openPanel = [NSOpenPanel openPanel]; 541 [openPanel setAllowsMultipleSelection:WKOpenPanelParametersGetAllowsMultipleFiles(parameters)]; 542 543 WKRetain(listener); 544 545 [openPanel beginSheetModalForWindow:[(BrowserWindowController *)clientInfo window] completionHandler:^(NSInteger result) { 546 if (result == NSFileHandlingPanelOKButton) { 547 WKMutableArrayRef fileURLs = WKMutableArrayCreate(); 548 549 NSURL *nsURL; 550 for (nsURL in [openPanel URLs]) { 551 WKURLRef wkURL = WKURLCreateWithCFURL((CFURLRef)nsURL); 552 WKArrayAppendItem(fileURLs, wkURL); 553 WKRelease(wkURL); 554 } 555 556 WKOpenPanelResultListenerChooseFiles(listener, fileURLs); 557 558 WKRelease(fileURLs); 559 } else 560 WKOpenPanelResultListenerCancel(listener); 561 562 WKRelease(listener); 563 }]; 564 } 565 566 - (void)awakeFromNib 567 { 568 _webView = [[WKView alloc] initWithFrame:[containerView frame] contextRef:_context]; 569 570 [containerView addSubview:_webView]; 571 [_webView setFrame:[containerView frame]]; 572 573 [_webView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; 574 575 WKPageLoaderClient loadClient = { 576 0, /* version */ 577 self, /* clientInfo */ 578 didStartProvisionalLoadForFrame, 579 didReceiveServerRedirectForProvisionalLoadForFrame, 580 didFailProvisionalLoadWithErrorForFrame, 581 didCommitLoadForFrame, 582 didFinishDocumentLoadForFrame, 583 didFinishLoadForFrame, 584 didFailLoadWithErrorForFrame, 585 didSameDocumentNavigationForFrame, 586 didReceiveTitleForFrame, 587 didFirstLayoutForFrame, 588 didFirstVisuallyNonEmptyLayoutForFrame, 589 didRemoveFrameFromHierarchy, 590 didDisplayInsecureContentForFrame, 591 didRunInsecureContentForFrame, 592 0, // canAuthenticateAgainstProtectionSpaceInFrame 593 0, // didReceiveAuthenticationChallengeInFrame 594 didStartProgress, 595 didChangeProgress, 596 didFinishProgress, 597 didBecomeUnresponsive, 598 didBecomeResponsive, 599 processDidExit, 600 didChangeBackForwardList, 601 0 // shouldGoToBackForwardItem 602 }; 603 WKPageSetPageLoaderClient(_webView.pageRef, &loadClient); 604 605 WKPagePolicyClient policyClient = { 606 0, /* version */ 607 self, /* clientInfo */ 608 decidePolicyForNavigationAction, 609 decidePolicyForNewWindowAction, 610 decidePolicyForResponse, 611 0 /* unableToImplementPolicy */ 612 }; 613 WKPageSetPagePolicyClient(_webView.pageRef, &policyClient); 614 615 WKPageUIClient uiClient = { 616 0, /* version */ 617 self, /* clientInfo */ 618 createNewPage, 619 showPage, 620 closePage, 621 0, /* takeFocus */ 622 0, /* focus */ 623 0, /* unfocus */ 624 runJavaScriptAlert, 625 runJavaScriptConfirm, 626 runJavaScriptPrompt, 627 setStatusText, 628 mouseDidMoveOverElement, 629 0, /* missingPluginButtonClicked */ 630 0, /* didNotHandleKeyEvent */ 631 0, /* toolbarsAreVisible */ 632 0, /* setToolbarsAreVisible */ 633 0, /* menuBarIsVisible */ 634 0, /* setMenuBarIsVisible */ 635 0, /* statusBarIsVisible */ 636 0, /* setStatusBarIsVisible */ 637 0, /* isResizable */ 638 0, /* setIsResizable */ 639 getWindowFrame, 640 setWindowFrame, 641 runBeforeUnloadConfirmPanel, 642 0, /* didDraw */ 643 0, /* pageDidScroll */ 644 0, /* exceededDatabaseQuota */ 645 runOpenPanel, 646 0, /* decidePolicyForGeolocationPermissionRequest */ 647 0, // headerHeight 648 0, // footerHeight 649 0, // drawHeader 650 0, // drawFooter 651 0, // printFrame 652 0, // showModal 653 0, // didCompleteRubberBandForMainFrame 654 0, // saveDataToFileInDownloadsFolder 655 }; 656 WKPageSetPageUIClient(_webView.pageRef, &uiClient); 657 } 658 659 - (void)didStartProgress 660 { 661 [progressIndicator setDoubleValue:0.0]; 662 [progressIndicator setHidden:NO]; 663 } 664 665 - (void)didChangeProgress:(double)value 666 { 667 [progressIndicator setDoubleValue:value]; 668 } 669 670 - (void)didFinishProgress 671 { 672 [progressIndicator setHidden:YES]; 673 [progressIndicator setDoubleValue:1.0]; 674 } 675 676 - (void)updateProvisionalURLForFrame:(WKFrameRef)frame 677 { 678 static WKURLRef emptyURL = 0; 679 if (!emptyURL) 680 emptyURL = WKURLCreateWithUTF8CString(""); 681 682 WKURLRef url = WKFrameCopyProvisionalURL(frame); 683 if (WKURLIsEqual(url, emptyURL)) { 684 WKRelease(url); 685 return; 686 } 687 688 CFURLRef cfSourceURL = WKURLCopyCFURL(0, url); 689 WKRelease(url); 690 691 [urlText setStringValue:(NSString*)CFURLGetString(cfSourceURL)]; 692 CFRelease(cfSourceURL); 693 } 694 695 - (void)didStartProvisionalLoadForFrame:(WKFrameRef)frame 696 { 697 if (!WKFrameIsMainFrame(frame)) 698 return; 699 700 [self updateProvisionalURLForFrame:frame]; 701 } 702 703 - (void)didReceiveServerRedirectForProvisionalLoadForFrame:(WKFrameRef)frame 704 { 705 if (!WKFrameIsMainFrame(frame)) 706 return; 707 708 [self updateProvisionalURLForFrame:frame]; 709 } 710 711 - (void)didFailProvisionalLoadWithErrorForFrame:(WKFrameRef)frame 712 { 713 if (!WKFrameIsMainFrame(frame)) 714 return; 715 716 [self updateProvisionalURLForFrame:frame]; 717 } 718 719 - (void)didFailLoadWithErrorForFrame:(WKFrameRef)frame 720 { 721 if (!WKFrameIsMainFrame(frame)) 722 return; 723 724 [self updateProvisionalURLForFrame:frame]; 725 } 726 727 - (void)didSameDocumentNavigationForFrame:(WKFrameRef)frame 728 { 729 } 730 731 - (void)didCommitLoadForFrame:(WKFrameRef)frame 732 { 733 } 734 735 - (void)loadURLString:(NSString *)urlString 736 { 737 // FIXME: We shouldn't have to set the url text here. 738 [urlText setStringValue:urlString]; 739 [self fetch:nil]; 740 } 741 742 - (IBAction)performFindPanelAction:(id)sender 743 { 744 [findPanelWindow makeKeyAndOrderFront:sender]; 745 } 746 747 - (IBAction)find:(id)sender 748 { 749 WKStringRef string = WKStringCreateWithCFString((CFStringRef)[sender stringValue]); 750 751 WKPageFindString(_webView.pageRef, string, kWKFindOptionsCaseInsensitive | kWKFindOptionsWrapAround | kWKFindOptionsShowFindIndicator | kWKFindOptionsShowOverlay, 100); 752 } 753 754 @end 755