2 * Copyright (C) 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #import "AppDelegate.h"
28 #import "BrowserWindowController.h"
29 #import "BrowserStatisticsWindowController.h"
31 #import <WebKit2/WKContextPrivate.h>
32 #import <WebKit2/WKStringCF.h>
33 #import <WebKit2/WKURLCF.h>
35 static NSString *defaultURL = @"http://www.webkit.org/";
37 @implementation BrowserAppDelegate
39 void didRecieveMessageFromInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo)
41 CFStringRef cfMessageName = WKStringCopyCFString(0, messageName);
43 WKTypeID typeID = WKGetTypeID(messageBody);
44 if (typeID == WKStringGetTypeID()) {
45 CFStringRef cfMessageBody = WKStringCopyCFString(0, (WKStringRef)messageBody);
46 LOG(@"ContextInjectedBundleClient - didRecieveMessage - MessageName: %@ MessageBody %@", cfMessageName, cfMessageBody);
47 CFRelease(cfMessageBody);
49 LOG(@"ContextInjectedBundleClient - didRecieveMessage - MessageName: %@ (MessageBody Unhandeled)\n", cfMessageName);
52 CFRelease(cfMessageName);
54 WKStringRef newMessageName = WKStringCreateWithCFString(CFSTR("Response"));
55 WKStringRef newMessageBody = WKStringCreateWithCFString(CFSTR("Roger that!"));
57 WKContextPostMessageToInjectedBundle(context, newMessageName, newMessageBody);
59 WKRelease(newMessageName);
60 WKRelease(newMessageBody);
63 // MARK: History Client Callbacks
65 static void didNavigateWithNavigationData(WKContextRef context, WKPageRef page, WKNavigationDataRef navigationData, WKFrameRef frame, const void *clientInfo)
67 WKStringRef wkTitle = WKNavigationDataCopyTitle(navigationData);
68 CFStringRef title = WKStringCopyCFString(0, wkTitle);
71 WKURLRef wkURL = WKNavigationDataCopyURL(navigationData);
72 CFURLRef url = WKURLCopyCFURL(0, wkURL);
75 LOG(@"HistoryClient - didNavigateWithNavigationData - title: %@ - url: %@", title, url);
80 static void didPerformClientRedirect(WKContextRef context, WKPageRef page, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef frame, const void *clientInfo)
82 CFURLRef cfSourceURL = WKURLCopyCFURL(0, sourceURL);
83 CFURLRef cfDestinationURL = WKURLCopyCFURL(0, destinationURL);
84 LOG(@"HistoryClient - didPerformClientRedirect - sourceURL: %@ - destinationURL: %@", cfSourceURL, cfDestinationURL);
85 CFRelease(cfSourceURL);
86 CFRelease(cfDestinationURL);
89 static void didPerformServerRedirect(WKContextRef context, WKPageRef page, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef frame, const void *clientInfo)
91 CFURLRef cfSourceURL = WKURLCopyCFURL(0, sourceURL);
92 CFURLRef cfDestinationURL = WKURLCopyCFURL(0, destinationURL);
93 LOG(@"HistoryClient - didPerformServerRedirect - sourceURL: %@ - destinationURL: %@", cfSourceURL, cfDestinationURL);
94 CFRelease(cfSourceURL);
95 CFRelease(cfDestinationURL);
98 static void didUpdateHistoryTitle(WKContextRef context, WKPageRef page, WKStringRef title, WKURLRef URL, WKFrameRef frame, const void *clientInfo)
100 CFStringRef cfTitle = WKStringCopyCFString(0, title);
101 CFURLRef cfURL = WKURLCopyCFURL(0, URL);
102 LOG(@"HistoryClient - didUpdateHistoryTitle - title: %@ - URL: %@", cfTitle, cfURL);
107 static void populateVisitedLinks(WKContextRef context, const void *clientInfo)
109 LOG(@"HistoryClient - populateVisitedLinks");
116 if ([NSEvent modifierFlags] & NSShiftKeyMask)
117 _currentProcessModel = kProcessModelSharedSecondaryThread;
119 _currentProcessModel = kProcessModelSharedSecondaryProcess;
121 WKContextHistoryClient historyClient = {
122 kWKContextHistoryClientCurrentVersion,
124 didNavigateWithNavigationData,
125 didPerformClientRedirect,
126 didPerformServerRedirect,
127 didUpdateHistoryTitle,
131 _threadContext = WKContextGetSharedThreadContext();
132 WKContextSetHistoryClient(_threadContext, &historyClient);
133 WKContextSetCacheModel(_threadContext, kWKCacheModelPrimaryWebBrowser);
135 CFStringRef bundlePathCF = (CFStringRef)[[NSBundle mainBundle] pathForAuxiliaryExecutable:@"WebBundle.bundle"];
136 WKStringRef bundlePath = WKStringCreateWithCFString(bundlePathCF);
138 _processContext = WKContextCreateWithInjectedBundlePath(bundlePath);
140 WKContextInjectedBundleClient bundleClient = {
141 kWKContextInjectedBundleClientCurrentVersion,
143 didRecieveMessageFromInjectedBundle,
146 WKContextSetInjectedBundleClient(_processContext, &bundleClient);
147 WKContextSetHistoryClient(_processContext, &historyClient);
148 WKContextSetCacheModel(_processContext, kWKCacheModelPrimaryWebBrowser);
150 WKRelease(bundlePath);
156 - (IBAction)newWindow:(id)sender
158 BrowserWindowController *controller = [[BrowserWindowController alloc] initWithContext:[self getCurrentContext]];
159 [[controller window] makeKeyAndOrderFront:sender];
161 [controller loadURLString:defaultURL];
164 - (WKContextRef)getCurrentContext
166 return (_currentProcessModel == kProcessModelSharedSecondaryThread) ? _threadContext : _processContext;
169 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
171 if ([menuItem action] == @selector(setSharedProcessProcessModel:))
172 [menuItem setState:_currentProcessModel == kProcessModelSharedSecondaryProcess ? NSOnState : NSOffState];
173 else if ([menuItem action] == @selector(setSharedThreadProcessModel:))
174 [menuItem setState:_currentProcessModel == kProcessModelSharedSecondaryThread ? NSOnState : NSOffState];
178 - (void)_setProcessModel:(ProcessModel)processModel
180 if (processModel == _currentProcessModel)
183 _currentProcessModel = processModel;
186 - (IBAction)setSharedProcessProcessModel:(id)sender
188 [self _setProcessModel:kProcessModelSharedSecondaryProcess];
191 - (IBAction)setSharedThreadProcessModel:(id)sender
193 [self _setProcessModel:kProcessModelSharedSecondaryThread];
196 - (IBAction)showStatisticsWindow:(id)sender
198 static BrowserStatisticsWindowController* windowController;
199 if (!windowController)
200 windowController = [[BrowserStatisticsWindowController alloc] initWithThreadedWKContextRef:_threadContext
201 processWKContextRef:_processContext];
203 [[windowController window] makeKeyAndOrderFront:self];
206 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
208 [self newWindow:self];
211 - (void)applicationWillTerminate:(NSNotification *)notification
213 NSArray* windows = [NSApp windows];
214 for (NSWindow* window in windows) {
215 id delegate = [window delegate];
216 if ([delegate isKindOfClass:[BrowserWindowController class]]) {
217 BrowserWindowController *controller = (BrowserWindowController *)delegate;
218 [controller applicationTerminating];
222 WKRelease(_processContext);
226 - (BrowserWindowController *)frontmostBrowserWindowController
228 NSArray* windows = [NSApp windows];
229 for (NSWindow* window in windows) {
230 id delegate = [window delegate];
231 if ([delegate isKindOfClass:[BrowserWindowController class]])
232 return (BrowserWindowController *)delegate;
238 - (IBAction)openDocument:(id)sender
240 NSOpenPanel *openPanel = [[NSOpenPanel openPanel] retain];
241 [openPanel beginForDirectory:nil
244 modelessDelegate:self
245 didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
249 - (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
252 if (returnCode != NSOKButton || ![[sheet filenames] count])
255 NSString* filePath = [[sheet filenames] objectAtIndex:0];
257 BrowserWindowController *controller = [self frontmostBrowserWindowController];
259 controller = [[BrowserWindowController alloc] initWithContext:[self getCurrentContext]];
260 [[controller window] makeKeyAndOrderFront:self];
263 [controller loadURLString:[[NSURL fileURLWithPath:filePath] absoluteString]];