1dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block/*
2dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2010 Apple Inc. All rights reserved.
3dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *
4dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Redistribution and use in source and binary forms, with or without
5dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * modification, are permitted provided that the following conditions
6dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * are met:
7dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 1. Redistributions of source code must retain the above copyright
8dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *    notice, this list of conditions and the following disclaimer.
9dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 2. Redistributions in binary form must reproduce the above copyright
10dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *    notice, this list of conditions and the following disclaimer in the
11dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *    documentation and/or other materials provided with the distribution.
12dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *
13dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * THE POSSIBILITY OF SUCH DAMAGE.
24dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block */
25dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
26dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#import "AppDelegate.h"
2721939df44de1705786c545cd1bf519d47250322dBen Murdoch
28dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#import "BrowserWindowController.h"
2921939df44de1705786c545cd1bf519d47250322dBen Murdoch#import "BrowserStatisticsWindowController.h"
30dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
3106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#import <WebKit2/WKContextPrivate.h>
320617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#import <WebKit2/WKStringCF.h>
330617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#import <WebKit2/WKURLCF.h>
3406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
35ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockstatic NSString *defaultURL = @"http://www.webkit.org/";
36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
37dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block@implementation BrowserAppDelegate
38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
39db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid didRecieveMessageFromInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo)
4006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
41db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    CFStringRef cfMessageName = WKStringCopyCFString(0, messageName);
42db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
43db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    WKTypeID typeID = WKGetTypeID(messageBody);
44db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    if (typeID == WKStringGetTypeID()) {
45db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        CFStringRef cfMessageBody = WKStringCopyCFString(0, (WKStringRef)messageBody);
46db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        LOG(@"ContextInjectedBundleClient - didRecieveMessage - MessageName: %@ MessageBody %@", cfMessageName, cfMessageBody);
47db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        CFRelease(cfMessageBody);
48db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    } else {
49db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        LOG(@"ContextInjectedBundleClient - didRecieveMessage - MessageName: %@ (MessageBody Unhandeled)\n", cfMessageName);
50db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    }
51db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
52db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    CFRelease(cfMessageName);
53db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
54db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    WKStringRef newMessageName = WKStringCreateWithCFString(CFSTR("Response"));
55db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    WKStringRef newMessageBody = WKStringCreateWithCFString(CFSTR("Roger that!"));
5606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
57db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    WKContextPostMessageToInjectedBundle(context, newMessageName, newMessageBody);
58db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
59e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    WKRelease(newMessageName);
60e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    WKRelease(newMessageBody);
6106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
6206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
63cad810f21b803229eb11403f9209855525a25d57Steve Block// MARK: History Client Callbacks
640617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
650617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenstatic void didNavigateWithNavigationData(WKContextRef context, WKPageRef page, WKNavigationDataRef navigationData, WKFrameRef frame, const void *clientInfo)
660617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
670617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    WKStringRef wkTitle = WKNavigationDataCopyTitle(navigationData);
680617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFStringRef title = WKStringCopyCFString(0, wkTitle);
69e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    WKRelease(wkTitle);
700617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
710617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    WKURLRef wkURL = WKNavigationDataCopyURL(navigationData);
720617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFURLRef url = WKURLCopyCFURL(0, wkURL);
73e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    WKRelease(wkURL);
740617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
750617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    LOG(@"HistoryClient - didNavigateWithNavigationData - title: %@ - url: %@", title, url);
760617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFRelease(title);
770617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFRelease(url);
780617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
790617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
800617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenstatic void didPerformClientRedirect(WKContextRef context, WKPageRef page, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef frame, const void *clientInfo)
810617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
820617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFURLRef cfSourceURL = WKURLCopyCFURL(0, sourceURL);
830617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFURLRef cfDestinationURL = WKURLCopyCFURL(0, destinationURL);
840617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    LOG(@"HistoryClient - didPerformClientRedirect - sourceURL: %@ - destinationURL: %@", cfSourceURL, cfDestinationURL);
850617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFRelease(cfSourceURL);
860617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFRelease(cfDestinationURL);
870617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
880617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
890617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenstatic void didPerformServerRedirect(WKContextRef context, WKPageRef page, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef frame, const void *clientInfo)
900617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
910617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFURLRef cfSourceURL = WKURLCopyCFURL(0, sourceURL);
920617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFURLRef cfDestinationURL = WKURLCopyCFURL(0, destinationURL);
930617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    LOG(@"HistoryClient - didPerformServerRedirect - sourceURL: %@ - destinationURL: %@", cfSourceURL, cfDestinationURL);
940617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFRelease(cfSourceURL);
950617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFRelease(cfDestinationURL);
960617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
970617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
980617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenstatic void didUpdateHistoryTitle(WKContextRef context, WKPageRef page, WKStringRef title, WKURLRef URL, WKFrameRef frame, const void *clientInfo)
990617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
1000617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFStringRef cfTitle = WKStringCopyCFString(0, title);
1010617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFURLRef cfURL = WKURLCopyCFURL(0, URL);
1020617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    LOG(@"HistoryClient - didUpdateHistoryTitle - title: %@ - URL: %@", cfTitle, cfURL);
1030617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFRelease(cfTitle);
1040617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    CFRelease(cfURL);
1050617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
1060617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
1070617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenstatic void populateVisitedLinks(WKContextRef context, const void *clientInfo)
1080617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
1090617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    LOG(@"HistoryClient - populateVisitedLinks");
1100617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
1110617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
112dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block- (id)init
113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    self = [super init];
115dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (self) {
116dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if ([NSEvent modifierFlags] & NSShiftKeyMask)
117f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            _currentProcessModel = kProcessModelSharedSecondaryThread;
118dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        else
119f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            _currentProcessModel = kProcessModelSharedSecondaryProcess;
12021939df44de1705786c545cd1bf519d47250322dBen Murdoch
1210617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        WKContextHistoryClient historyClient = {
1220617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            0,
1230617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            self,
1240617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            didNavigateWithNavigationData,
1250617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            didPerformClientRedirect,
1260617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            didPerformServerRedirect,
1270617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            didUpdateHistoryTitle,
1280617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            populateVisitedLinks
1290617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        };
130a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
131f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        _threadContext = WKContextGetSharedThreadContext();
132f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        WKContextSetHistoryClient(_threadContext, &historyClient);
133f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        WKContextSetCacheModel(_threadContext, kWKCacheModelPrimaryWebBrowser);
13421939df44de1705786c545cd1bf519d47250322dBen Murdoch
13506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        CFStringRef bundlePathCF = (CFStringRef)[[NSBundle mainBundle] pathForAuxiliaryExecutable:@"WebBundle.bundle"];
13606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        WKStringRef bundlePath = WKStringCreateWithCFString(bundlePathCF);
13706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
138f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        _processContext = WKContextCreateWithInjectedBundlePath(bundlePath);
13906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
14006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        WKContextInjectedBundleClient bundleClient = {
14106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            0,      /* version */
14206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            0,      /* clientInfo */
14368513a70bcd92384395513322f1b801e7bf9c729Steve Block            didRecieveMessageFromInjectedBundle,
14468513a70bcd92384395513322f1b801e7bf9c729Steve Block            0
14506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        };
146f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        WKContextSetInjectedBundleClient(_processContext, &bundleClient);
147f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        WKContextSetHistoryClient(_processContext, &historyClient);
148f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        WKContextSetCacheModel(_processContext, kWKCacheModelPrimaryWebBrowser);
14906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
150e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        WKRelease(bundlePath);
151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
152dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
153dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return self;
154dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
155dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
156dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block- (IBAction)newWindow:(id)sender
157dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
158f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    BrowserWindowController *controller = [[BrowserWindowController alloc] initWithContext:[self getCurrentContext]];
159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    [[controller window] makeKeyAndOrderFront:sender];
160dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
161dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    [controller loadURLString:defaultURL];
162dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
163dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
164f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch- (WKContextRef)getCurrentContext
165dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
166f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return (_currentProcessModel == kProcessModelSharedSecondaryThread) ? _threadContext : _processContext;
167dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
168dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
169dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
170dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
171dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if ([menuItem action] == @selector(setSharedProcessProcessModel:))
172f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        [menuItem setState:_currentProcessModel == kProcessModelSharedSecondaryProcess ? NSOnState : NSOffState];
173dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else if ([menuItem action] == @selector(setSharedThreadProcessModel:))
174f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        [menuItem setState:_currentProcessModel == kProcessModelSharedSecondaryThread ? NSOnState : NSOffState];
175dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return YES;
176dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
177dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
17806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen- (void)_setProcessModel:(ProcessModel)processModel
179dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
180f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (processModel == _currentProcessModel)
181dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return;
182dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
183f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    _currentProcessModel = processModel;
184dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
185dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
186dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block- (IBAction)setSharedProcessProcessModel:(id)sender
187dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
18806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    [self _setProcessModel:kProcessModelSharedSecondaryProcess];
189dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
190dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
191dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block- (IBAction)setSharedThreadProcessModel:(id)sender
192dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
19306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    [self _setProcessModel:kProcessModelSharedSecondaryThread];
194dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
195dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
19621939df44de1705786c545cd1bf519d47250322dBen Murdoch- (IBAction)showStatisticsWindow:(id)sender
19721939df44de1705786c545cd1bf519d47250322dBen Murdoch{
19821939df44de1705786c545cd1bf519d47250322dBen Murdoch    static BrowserStatisticsWindowController* windowController;
19921939df44de1705786c545cd1bf519d47250322dBen Murdoch    if (!windowController)
200f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        windowController = [[BrowserStatisticsWindowController alloc] initWithThreadedWKContextRef:_threadContext
201f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                                                                               processWKContextRef:_processContext];
20221939df44de1705786c545cd1bf519d47250322dBen Murdoch
20321939df44de1705786c545cd1bf519d47250322dBen Murdoch    [[windowController window] makeKeyAndOrderFront:self];
20421939df44de1705786c545cd1bf519d47250322dBen Murdoch}
20521939df44de1705786c545cd1bf519d47250322dBen Murdoch
206dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
207dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
208dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    [self newWindow:self];
209dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
210dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
211dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block- (void)applicationWillTerminate:(NSNotification *)notification
212dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
213dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    NSArray* windows = [NSApp windows];
214dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    for (NSWindow* window in windows) {
21521939df44de1705786c545cd1bf519d47250322dBen Murdoch        id delegate = [window delegate];
21621939df44de1705786c545cd1bf519d47250322dBen Murdoch        if ([delegate isKindOfClass:[BrowserWindowController class]]) {
21721939df44de1705786c545cd1bf519d47250322dBen Murdoch            BrowserWindowController *controller = (BrowserWindowController *)delegate;
21821939df44de1705786c545cd1bf519d47250322dBen Murdoch            [controller applicationTerminating];
21921939df44de1705786c545cd1bf519d47250322dBen Murdoch        }
220dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
221dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
222f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    WKRelease(_processContext);
223f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    _processContext = 0;
224dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
225dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
226ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block- (BrowserWindowController *)frontmostBrowserWindowController
227ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
228ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    NSArray* windows = [NSApp windows];
229ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    for (NSWindow* window in windows) {
230ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        id delegate = [window delegate];
231ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if ([delegate isKindOfClass:[BrowserWindowController class]])
232ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return (BrowserWindowController *)delegate;
233ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
234ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
235ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    return 0;
236ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
237ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
238ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block- (IBAction)openDocument:(id)sender
239ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
240ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    NSOpenPanel *openPanel = [[NSOpenPanel openPanel] retain];
241ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    [openPanel beginForDirectory:nil
242ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        file:nil
243ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        types:nil
244ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        modelessDelegate:self
245ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
246ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        contextInfo:0];
247ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
248ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
249ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
250ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
251ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    [sheet autorelease];
252ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (returnCode != NSOKButton || ![[sheet filenames] count])
253ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return;
254ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
255ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    NSString* filePath = [[sheet filenames] objectAtIndex:0];
256ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
257ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    BrowserWindowController *controller = [self frontmostBrowserWindowController];
258ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (!controller) {
259f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        controller = [[BrowserWindowController alloc] initWithContext:[self getCurrentContext]];
260ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        [[controller window] makeKeyAndOrderFront:self];
261ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
262ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
263ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    [controller loadURLString:[[NSURL fileURLWithPath:filePath] absoluteString]];
264ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
265ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
266dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block@end
267