diff -r 000000000000 -r 4f2f89ce4247 WebKitTools/MiniBrowser/mac/BrowserWindowController.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebKitTools/MiniBrowser/mac/BrowserWindowController.m Fri Sep 17 09:02:29 2010 +0300 @@ -0,0 +1,465 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "BrowserWindowController.h" + +#import +#import +#import + +@interface BrowserWindowController () +- (void)didStartProgress; +- (void)didChangeProgress:(double)value; +- (void)didFinishProgress; +- (void)didStartProvisionalLoadForFrame:(WKFrameRef)frame; +- (void)didCommitLoadForFrame:(WKFrameRef)frame; +- (void)didReceiveServerRedirectForProvisionalLoadForFrame:(WKFrameRef)frame; +- (void)didFailProvisionalLoadWithErrorForFrame:(WKFrameRef)frame; +- (void)didFailLoadWithErrorForFrame:(WKFrameRef)frame; +@end + +@implementation BrowserWindowController + +- (id)initWithPageNamespace:(WKPageNamespaceRef)pageNamespace +{ + if ((self = [super initWithWindowNibName:@"BrowserWindow"])) + _pageNamespace = WKPageNamespaceRetain(pageNamespace); + + return self; +} + +- (void)dealloc +{ + assert(!_pageNamespace); + [super dealloc]; +} + +- (IBAction)fetch:(id)sender +{ + CFURLRef cfURL = CFURLCreateWithString(0, (CFStringRef)[urlText stringValue], 0); + WKURLRef url = WKURLCreateWithCFURL(cfURL); + CFRelease(cfURL); + + WKPageLoadURL(_webView.pageRef, url); + WKURLRelease(url); +} + +- (IBAction)showHideWebView:(id)sender +{ + BOOL hidden = ![_webView isHidden]; + + [_webView setHidden:hidden]; +} + +- (IBAction)removeReinsertWebView:(id)sender +{ + if ([_webView window]) { + [_webView retain]; + [_webView removeFromSuperview]; + } else { + [containerView addSubview:_webView]; + [_webView release]; + } +} + +- (BOOL)validateMenuItem:(NSMenuItem *)menuItem +{ + if ([menuItem action] == @selector(showHideWebView:)) + [menuItem setTitle:[_webView isHidden] ? @"Show Web View" : @"Hide Web View"]; + else if ([menuItem action] == @selector(removeReinsertWebView:)) + [menuItem setTitle:[_webView window] ? @"Remove Web View" : @"Insert Web View"]; + return YES; +} + +- (IBAction)reload:(id)sender +{ + WKPageReload(_webView.pageRef); +} + +- (IBAction)forceRepaint:(id)sender +{ + [_webView setNeedsDisplay:YES]; +} + +- (IBAction)goBack:(id)sender +{ + WKPageGoBack(_webView.pageRef); +} + +- (IBAction)goForward:(id)sender +{ + WKPageGoForward(_webView.pageRef); +} + +- (BOOL)validateUserInterfaceItem:(id )item +{ + SEL action = [item action]; + + if (action == @selector(goBack:)) + return _webView && WKPageCanGoBack(_webView.pageRef); + + if (action == @selector(goForward:)) + return _webView && WKPageCanGoForward(_webView.pageRef); + + return YES; +} + +- (void)validateToolbar +{ + [toolbar validateVisibleItems]; +} + +- (BOOL)windowShouldClose:(id)sender +{ + LOG(@"windowShouldClose"); + BOOL canCloseImmediately = WKPageTryClose(_webView.pageRef); + return canCloseImmediately; +} + +- (void)windowWillClose:(NSNotification *)notification +{ + WKPageNamespaceRelease(_pageNamespace); + _pageNamespace = 0; +} + +- (void)applicationTerminating +{ + WKPageClose(_webView.pageRef); + WKPageRelease(_webView.pageRef); +} + +#pragma mark Loader Client Callbacks + +static void _didStartProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo) +{ + [(BrowserWindowController *)clientInfo didStartProvisionalLoadForFrame:frame]; +} + +static void _didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo) +{ + [(BrowserWindowController *)clientInfo didReceiveServerRedirectForProvisionalLoadForFrame:frame]; +} + +static void _didFailProvisionalLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo) +{ + [(BrowserWindowController *)clientInfo didFailProvisionalLoadWithErrorForFrame:frame]; +} + +static void _didCommitLoadForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo) +{ + [(BrowserWindowController *)clientInfo didCommitLoadForFrame:frame]; +} + +static void _didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo) +{ + LOG(@"didFinishLoadForFrame"); +} + +static void _didFailLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo) +{ + [(BrowserWindowController *)clientInfo didFailLoadWithErrorForFrame:frame]; +} + +static void _didReceiveTitleForFrame(WKPageRef page, WKStringRef title, WKFrameRef frame, const void *clientInfo) +{ + CFStringRef cfTitle = WKStringCopyCFString(0, title); + LOG(@"didReceiveTitleForFrame \"%@\"", (NSString *)cfTitle); + CFRelease(cfTitle); +} + +static void _didFirstLayoutForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo) +{ + LOG(@"didFirstLayoutForFrame"); +} + +static void _didFirstVisuallyNonEmptyLayoutForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo) +{ + LOG(@"didFirstVisuallyNonEmptyLayoutForFrame"); +} + +static void _didStartProgress(WKPageRef page, const void *clientInfo) +{ + [(BrowserWindowController *)clientInfo didStartProgress]; +} + +static void _didChangeProgress(WKPageRef page, const void *clientInfo) +{ + [(BrowserWindowController *)clientInfo didChangeProgress:WKPageGetEstimatedProgress(page)]; +} + +static void _didFinishProgress(WKPageRef page, const void *clientInfo) +{ + [(BrowserWindowController *)clientInfo didFinishProgress]; +} + +static void _didBecomeUnresponsive(WKPageRef page, const void *clientInfo) +{ + LOG(@"didBecomeUnresponsive"); +} + +static void _didBecomeResponsive(WKPageRef page, const void *clientInfo) +{ + LOG(@"didBecomeResponsive"); +} + +static void _didChangeBackForwardList(WKPageRef page, const void *clientInfo) +{ + [(BrowserWindowController *)clientInfo validateToolbar]; +} + +#pragma mark Policy Client Callbacks + +static void _decidePolicyForNavigationAction(WKPageRef page, WKFrameNavigationType navigationType, WKURLRef url, WKFrameRef frame, WKFramePolicyListenerRef listener, const void *clientInfo) +{ + LOG(@"decidePolicyForNavigationAction"); + WKFramePolicyListenerUse(listener); +} + +static void _decidePolicyForNewWindowAction(WKPageRef page, WKFrameNavigationType navigationType, WKURLRef url, WKFrameRef frame, WKFramePolicyListenerRef listener, const void *clientInfo) +{ + LOG(@"decidePolicyForNewWindowAction"); + WKFramePolicyListenerUse(listener); +} + +static void _decidePolicyForMIMEType(WKPageRef page, WKStringRef MIMEType, WKURLRef url, WKFrameRef frame, WKFramePolicyListenerRef listener, const void *clientInfo) +{ + WKFramePolicyListenerUse(listener); +} + +#pragma mark UI Client Callbacks + +static WKPageRef _createNewPage(WKPageRef page, const void* clientInfo) +{ + LOG(@"createNewPage"); + BrowserWindowController *controller = [[BrowserWindowController alloc] initWithPageNamespace:WKPageGetPageNamespace(page)]; + [controller loadWindow]; + + return controller->_webView.pageRef; +} + +static void _showPage(WKPageRef page, const void *clientInfo) +{ + LOG(@"showPage"); + [[(BrowserWindowController *)clientInfo window] orderFront:nil]; +} + +static void _closePage(WKPageRef page, const void *clientInfo) +{ + LOG(@"closePage"); + WKPageClose(page); + [[(BrowserWindowController *)clientInfo window] close]; + WKPageRelease(page); +} + +static void _runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void* clientInfo) +{ + NSAlert* alert = [[NSAlert alloc] init]; + + CFURLRef cfURL = WKURLCopyCFURL(0, WKFrameGetURL(frame)); + [alert setMessageText:[NSString stringWithFormat:@"JavaScript Alert from %@.", [(NSURL *)cfURL absoluteString]]]; + CFRelease(cfURL); + + CFStringRef cfAlertText = WKStringCopyCFString(0, alertText); + [alert setInformativeText:(NSString *)alertText]; + CFRelease(cfAlertText); + + [alert addButtonWithTitle:@"OK"]; + + [alert runModal]; + [alert release]; +} + + +#pragma mark History Client Callbacks + +static void _didNavigateWithNavigationData(WKPageRef page, WKNavigationDataRef navigationData, WKFrameRef frame, const void *clientInfo) +{ + CFStringRef title = WKStringCopyCFString(0, WKNavigationDataGetTitle(navigationData)); + CFURLRef url = WKURLCopyCFURL(0, WKNavigationDataGetURL(navigationData)); + LOG(@"HistoryClient - didNavigateWithNavigationData - title: %@ - url: %@", title, url); + CFRelease(title); + CFRelease(url); +} + +static void _didPerformClientRedirect(WKPageRef page, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef frame, const void *clientInfo) +{ + CFURLRef cfSourceURL = WKURLCopyCFURL(0, sourceURL); + CFURLRef cfDestinationURL = WKURLCopyCFURL(0, destinationURL); + LOG(@"HistoryClient - didPerformClientRedirect - sourceURL: %@ - destinationURL: %@", cfSourceURL, cfDestinationURL); + CFRelease(cfSourceURL); + CFRelease(cfDestinationURL); +} + +static void _didPerformServerRedirect(WKPageRef page, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef frame, const void *clientInfo) +{ + CFURLRef cfSourceURL = WKURLCopyCFURL(0, sourceURL); + CFURLRef cfDestinationURL = WKURLCopyCFURL(0, destinationURL); + LOG(@"HistoryClient - didPerformServerRedirect - sourceURL: %@ - destinationURL: %@", cfSourceURL, cfDestinationURL); + CFRelease(cfSourceURL); + CFRelease(cfDestinationURL); +} + +static void _didUpdateHistoryTitle(WKPageRef page, WKStringRef title, WKURLRef URL, WKFrameRef frame, const void *clientInfo) +{ + CFStringRef cfTitle = WKStringCopyCFString(0, title); + CFURLRef cfURL = WKURLCopyCFURL(0, URL); + LOG(@"HistoryClient - didUpdateHistoryTitle - title: %@ - URL: %@", cfTitle, cfURL); + CFRelease(cfTitle); + CFRelease(cfURL); +} + +- (void)awakeFromNib +{ + _webView = [[WKView alloc] initWithFrame:[containerView frame] pageNamespaceRef:_pageNamespace]; + + [containerView addSubview:_webView]; + [_webView setFrame:[containerView frame]]; + + [_webView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + + WKPageLoaderClient loadClient = { + 0, /* version */ + self, /* clientInfo */ + _didStartProvisionalLoadForFrame, + _didReceiveServerRedirectForProvisionalLoadForFrame, + _didFailProvisionalLoadWithErrorForFrame, + _didCommitLoadForFrame, + _didFinishLoadForFrame, + _didFailLoadWithErrorForFrame, + _didReceiveTitleForFrame, + _didFirstLayoutForFrame, + _didFirstVisuallyNonEmptyLayoutForFrame, + _didStartProgress, + _didChangeProgress, + _didFinishProgress, + _didBecomeUnresponsive, + _didBecomeResponsive, + _didChangeBackForwardList + }; + WKPageSetPageLoaderClient(_webView.pageRef, &loadClient); + + WKPagePolicyClient policyClient = { + 0, /* version */ + self, /* clientInfo */ + _decidePolicyForNavigationAction, + _decidePolicyForNewWindowAction, + _decidePolicyForMIMEType + }; + WKPageSetPagePolicyClient(_webView.pageRef, &policyClient); + + WKPageUIClient uiClient = { + 0, /* version */ + self, /* clientInfo */ + _createNewPage, + _showPage, + _closePage, + _runJavaScriptAlert + }; + WKPageSetPageUIClient(_webView.pageRef, &uiClient); + + WKPageHistoryClient historyClient = { + 0, + self, + _didNavigateWithNavigationData, + _didPerformClientRedirect, + _didPerformServerRedirect, + _didUpdateHistoryTitle, + }; + + WKPageSetPageHistoryClient(_webView.pageRef, &historyClient); +} + +- (void)didStartProgress +{ + [progressIndicator setDoubleValue:0.0]; + [progressIndicator setHidden:NO]; +} + +- (void)didChangeProgress:(double)value +{ + [progressIndicator setDoubleValue:value]; +} + +- (void)didFinishProgress +{ + [progressIndicator setHidden:YES]; + [progressIndicator setDoubleValue:1.0]; +} + +- (void)updateProvisionalURLForFrame:(WKFrameRef)frame +{ + WKURLRef url = WKFrameGetProvisionalURL(frame); + if (!url) + return; + + CFURLRef cfSourceURL = WKURLCopyCFURL(0, url); + [urlText setStringValue:(NSString*)CFURLGetString(cfSourceURL)]; + CFRelease(cfSourceURL); +} + +- (void)didStartProvisionalLoadForFrame:(WKFrameRef)frame +{ + if (!WKFrameIsMainFrame(frame)) + return; + + [self updateProvisionalURLForFrame:frame]; +} + +- (void)didReceiveServerRedirectForProvisionalLoadForFrame:(WKFrameRef)frame +{ + if (!WKFrameIsMainFrame(frame)) + return; + + [self updateProvisionalURLForFrame:frame]; +} + +- (void)didFailProvisionalLoadWithErrorForFrame:(WKFrameRef)frame +{ + if (!WKFrameIsMainFrame(frame)) + return; + + [self updateProvisionalURLForFrame:frame]; +} + +- (void)didFailLoadWithErrorForFrame:(WKFrameRef)frame +{ + if (!WKFrameIsMainFrame(frame)) + return; + + [self updateProvisionalURLForFrame:frame]; +} + +- (void)didCommitLoadForFrame:(WKFrameRef)frame +{ +} + +- (void)loadURLString:(NSString *)urlString +{ + // FIXME: We shouldn't have to set the url text here. + [urlText setStringValue:urlString]; + [self fetch:nil]; +} + +@end