WebKitTools/MiniBrowser/mac/BrowserWindowController.m
changeset 0 4f2f89ce4247
--- /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 <WebKit2/WKPagePrivate.h>
+#import <WebKit2/WKStringCF.h>
+#import <WebKit2/WKURLCF.h>
+
+@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 <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;
+}
+
+- (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