BrowserWindowController.m revision f05b935882198ccf7d81675736e3aeb089c5113a
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#pragma 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, const void *clientInfo) 355{ 356 [(BrowserWindowController *)clientInfo validateToolbar]; 357} 358 359#pragma mark Policy Client Callbacks 360 361static void decidePolicyForNavigationAction(WKPageRef page, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRef url, WKFrameRef frame, WKFramePolicyListenerRef listener, const void *clientInfo) 362{ 363 LOG(@"decidePolicyForNavigationAction"); 364 WKFramePolicyListenerUse(listener); 365} 366 367static void decidePolicyForNewWindowAction(WKPageRef page, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRef url, WKFrameRef frame, WKFramePolicyListenerRef listener, const void *clientInfo) 368{ 369 LOG(@"decidePolicyForNewWindowAction"); 370 WKFramePolicyListenerUse(listener); 371} 372 373static void decidePolicyForMIMEType(WKPageRef page, WKStringRef MIMEType, WKURLRef url, WKFrameRef frame, WKFramePolicyListenerRef listener, const void *clientInfo) 374{ 375 WKFramePolicyListenerUse(listener); 376} 377 378#pragma 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 }; 602 WKPageSetPageLoaderClient(_webView.pageRef, &loadClient); 603 604 WKPagePolicyClient policyClient = { 605 0, /* version */ 606 self, /* clientInfo */ 607 decidePolicyForNavigationAction, 608 decidePolicyForNewWindowAction, 609 decidePolicyForMIMEType 610 }; 611 WKPageSetPagePolicyClient(_webView.pageRef, &policyClient); 612 613 WKPageUIClient uiClient = { 614 0, /* version */ 615 self, /* clientInfo */ 616 createNewPage, 617 showPage, 618 closePage, 619 runJavaScriptAlert, 620 runJavaScriptConfirm, 621 runJavaScriptPrompt, 622 setStatusText, 623 mouseDidMoveOverElement, 624 0, /* missingPluginButtonClicked */ 625 0, /* didNotHandleKeyEvent */ 626 0, /* toolbarsAreVisible */ 627 0, /* setToolbarsAreVisible */ 628 0, /* menuBarIsVisible */ 629 0, /* setMenuBarIsVisible */ 630 0, /* statusBarIsVisible */ 631 0, /* setStatusBarIsVisible */ 632 0, /* isResizable */ 633 0, /* setIsResizable */ 634 getWindowFrame, 635 setWindowFrame, 636 runBeforeUnloadConfirmPanel, 637 0, /* didDraw */ 638 0, /* pageDidScroll */ 639 0, /* exceededDatabaseQuota */ 640 runOpenPanel 641 }; 642 WKPageSetPageUIClient(_webView.pageRef, &uiClient); 643} 644 645- (void)didStartProgress 646{ 647 [progressIndicator setDoubleValue:0.0]; 648 [progressIndicator setHidden:NO]; 649} 650 651- (void)didChangeProgress:(double)value 652{ 653 [progressIndicator setDoubleValue:value]; 654} 655 656- (void)didFinishProgress 657{ 658 [progressIndicator setHidden:YES]; 659 [progressIndicator setDoubleValue:1.0]; 660} 661 662- (void)updateProvisionalURLForFrame:(WKFrameRef)frame 663{ 664 static WKURLRef emptyURL = 0; 665 if (!emptyURL) 666 emptyURL = WKURLCreateWithUTF8CString(""); 667 668 WKURLRef url = WKFrameCopyProvisionalURL(frame); 669 if (WKURLIsEqual(url, emptyURL)) { 670 WKRelease(url); 671 return; 672 } 673 674 CFURLRef cfSourceURL = WKURLCopyCFURL(0, url); 675 WKRelease(url); 676 677 [urlText setStringValue:(NSString*)CFURLGetString(cfSourceURL)]; 678 CFRelease(cfSourceURL); 679} 680 681- (void)didStartProvisionalLoadForFrame:(WKFrameRef)frame 682{ 683 if (!WKFrameIsMainFrame(frame)) 684 return; 685 686 [self updateProvisionalURLForFrame:frame]; 687} 688 689- (void)didReceiveServerRedirectForProvisionalLoadForFrame:(WKFrameRef)frame 690{ 691 if (!WKFrameIsMainFrame(frame)) 692 return; 693 694 [self updateProvisionalURLForFrame:frame]; 695} 696 697- (void)didFailProvisionalLoadWithErrorForFrame:(WKFrameRef)frame 698{ 699 if (!WKFrameIsMainFrame(frame)) 700 return; 701 702 [self updateProvisionalURLForFrame:frame]; 703} 704 705- (void)didFailLoadWithErrorForFrame:(WKFrameRef)frame 706{ 707 if (!WKFrameIsMainFrame(frame)) 708 return; 709 710 [self updateProvisionalURLForFrame:frame]; 711} 712 713- (void)didSameDocumentNavigationForFrame:(WKFrameRef)frame 714{ 715} 716 717- (void)didCommitLoadForFrame:(WKFrameRef)frame 718{ 719} 720 721- (void)loadURLString:(NSString *)urlString 722{ 723 // FIXME: We shouldn't have to set the url text here. 724 [urlText setStringValue:urlString]; 725 [self fetch:nil]; 726} 727 728- (IBAction)performFindPanelAction:(id)sender 729{ 730 [findPanelWindow makeKeyAndOrderFront:sender]; 731} 732 733- (IBAction)find:(id)sender 734{ 735 WKStringRef string = WKStringCreateWithCFString((CFStringRef)[sender stringValue]); 736 737 WKPageFindString(_webView.pageRef, string, kWKFindOptionsCaseInsensitive | kWKFindOptionsWrapAround | kWKFindOptionsShowFindIndicator | kWKFindOptionsShowOverlay, 100); 738} 739 740@end 741