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 252static void didStartProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 253{ 254 [(BrowserWindowController *)clientInfo didStartProvisionalLoadForFrame:frame]; 255} 256 257static void didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 258{ 259 [(BrowserWindowController *)clientInfo didReceiveServerRedirectForProvisionalLoadForFrame:frame]; 260} 261 262static void didFailProvisionalLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, WKErrorRef error, WKTypeRef userData, const void *clientInfo) 263{ 264 [(BrowserWindowController *)clientInfo didFailProvisionalLoadWithErrorForFrame:frame]; 265} 266 267static void didCommitLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 268{ 269 [(BrowserWindowController *)clientInfo didCommitLoadForFrame:frame]; 270} 271 272static void didFinishDocumentLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 273{ 274 LOG(@"didFinishDocumentLoadForFrame"); 275} 276 277static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 278{ 279 LOG(@"didFinishLoadForFrame"); 280} 281 282static void didFailLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, WKErrorRef error, WKTypeRef userData, const void *clientInfo) 283{ 284 [(BrowserWindowController *)clientInfo didFailLoadWithErrorForFrame:frame]; 285} 286 287static void didSameDocumentNavigationForFrame(WKPageRef page, WKFrameRef frame, WKSameDocumentNavigationType type, WKTypeRef userData, const void *clientInfo) 288{ 289 [(BrowserWindowController *)clientInfo didSameDocumentNavigationForFrame:frame]; 290} 291 292static 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 299static void didFirstLayoutForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 300{ 301 LOG(@"didFirstLayoutForFrame"); 302} 303 304static void didFirstVisuallyNonEmptyLayoutForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 305{ 306 LOG(@"didFirstVisuallyNonEmptyLayoutForFrame"); 307} 308 309static void didRemoveFrameFromHierarchy(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 310{ 311 LOG(@"didRemoveFrameFromHierarchy"); 312} 313 314static void didDisplayInsecureContentForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 315{ 316 LOG(@"didDisplayInsecureContentForFrame"); 317} 318 319static void didRunInsecureContentForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) 320{ 321 LOG(@"didRunInsecureContentForFrame"); 322} 323 324static void didStartProgress(WKPageRef page, const void *clientInfo) 325{ 326 [(BrowserWindowController *)clientInfo didStartProgress]; 327} 328 329static void didChangeProgress(WKPageRef page, const void *clientInfo) 330{ 331 [(BrowserWindowController *)clientInfo didChangeProgress:WKPageGetEstimatedProgress(page)]; 332} 333 334static void didFinishProgress(WKPageRef page, const void *clientInfo) 335{ 336 [(BrowserWindowController *)clientInfo didFinishProgress]; 337} 338 339static void didBecomeUnresponsive(WKPageRef page, const void *clientInfo) 340{ 341 LOG(@"didBecomeUnresponsive"); 342} 343 344static void didBecomeResponsive(WKPageRef page, const void *clientInfo) 345{ 346 LOG(@"didBecomeResponsive"); 347} 348 349static void processDidExit(WKPageRef page, const void *clientInfo) 350{ 351 LOG(@"processDidExit"); 352} 353 354static void didChangeBackForwardList(WKPageRef page, WKBackForwardListItemRef addedItem, WKArrayRef removedItems, const void *clientInfo) 355{ 356 [(BrowserWindowController *)clientInfo validateToolbar]; 357} 358 359// MARK: Policy Client Callbacks 360 361static 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 367static 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 373static 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 380static 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 389static void showPage(WKPageRef page, const void *clientInfo) 390{ 391 LOG(@"showPage"); 392 [[(BrowserWindowController *)clientInfo window] orderFront:nil]; 393} 394 395static void closePage(WKPageRef page, const void *clientInfo) 396{ 397 LOG(@"closePage"); 398 WKPageClose(page); 399 [[(BrowserWindowController *)clientInfo window] close]; 400 WKRelease(page); 401} 402 403static 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 424static 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 448static 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 488static void setStatusText(WKPageRef page, WKStringRef text, const void* clientInfo) 489{ 490 LOG(@"setStatusText"); 491} 492 493static void mouseDidMoveOverElement(WKPageRef page, WKEventModifiers modifiers, WKTypeRef userData, const void *clientInfo) 494{ 495 LOG(@"mouseDidMoveOverElement"); 496} 497 498static 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 509static 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 514static 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 538static 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