blob: 0e5131122bf11a3090de584ec4e23fe3212d95c1 [file] [log] [blame]
/*
* 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 <WebKit2/WKPagePrivate.h>
#import <WebKit2/WKStringCF.h>
#import <WebKit2/WKURLCF.h>
@interface BrowserWindowController ()
- (void)didStartProgress;
- (void)didChangeProgress:(double)value;
- (void)didFinishProgress;
@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 <NSValidatedUserInterfaceItem>)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;
}
- (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)
{
LOG(@"didStartProvisionalLoadForFrame");
}
static void _didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
{
LOG(@"didReceiveServerRedirectForProvisionalLoadForFrame");
}
static void _didFailProvisionalLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
{
LOG(@"didFailProvisionalLoadWithErrorForFrame");
}
static void _didCommitLoadForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
{
LOG(@"didCommitLoadForFrame");
}
static void _didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
{
LOG(@"didFinishLoadForFrame");
}
static void _didFailLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
{
LOG(@"didFailLoadWithErrorForFrame");
}
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");
}
#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
};
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)loadURLString:(NSString *)urlString
{
// FIXME: We shouldn't have to set the url text here.
[urlText setStringValue:urlString];
[self fetch:nil];
}
@end