AppDelegate.m 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. * Copyright (C) 2010 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  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.
  12. *
  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.
  24. */
  25. #import "AppDelegate.h"
  26. #import "WK1BrowserWindowController.h"
  27. #import "WK2BrowserWindowController.h"
  28. #import <WebKit2/WKContextPrivate.h>
  29. #import <WebKit2/WKStringCF.h>
  30. #import <WebKit2/WKURLCF.h>
  31. static NSString *defaultURL = @"http://www.webkit.org/";
  32. enum {
  33. WebKit1NewWindowTag = 1,
  34. WebKit2NewWindowTag = 2
  35. };
  36. @implementation BrowserAppDelegate
  37. void didReceiveMessageFromInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo)
  38. {
  39. CFStringRef cfMessageName = WKStringCopyCFString(0, messageName);
  40. WKTypeID typeID = WKGetTypeID(messageBody);
  41. if (typeID == WKStringGetTypeID()) {
  42. CFStringRef cfMessageBody = WKStringCopyCFString(0, (WKStringRef)messageBody);
  43. LOG(@"ContextInjectedBundleClient - didReceiveMessage - MessageName: %@ MessageBody %@", cfMessageName, cfMessageBody);
  44. CFRelease(cfMessageBody);
  45. } else {
  46. LOG(@"ContextInjectedBundleClient - didReceiveMessage - MessageName: %@ (MessageBody Unhandled)\n", cfMessageName);
  47. }
  48. CFRelease(cfMessageName);
  49. WKStringRef newMessageName = WKStringCreateWithCFString(CFSTR("Response"));
  50. WKStringRef newMessageBody = WKStringCreateWithCFString(CFSTR("Roger that!"));
  51. WKContextPostMessageToInjectedBundle(context, newMessageName, newMessageBody);
  52. WKRelease(newMessageName);
  53. WKRelease(newMessageBody);
  54. }
  55. // MARK: History Client Callbacks
  56. static void didNavigateWithNavigationData(WKContextRef context, WKPageRef page, WKNavigationDataRef navigationData, WKFrameRef frame, const void *clientInfo)
  57. {
  58. WKStringRef wkTitle = WKNavigationDataCopyTitle(navigationData);
  59. CFStringRef title = WKStringCopyCFString(0, wkTitle);
  60. WKRelease(wkTitle);
  61. WKURLRef wkURL = WKNavigationDataCopyURL(navigationData);
  62. CFURLRef url = WKURLCopyCFURL(0, wkURL);
  63. WKRelease(wkURL);
  64. LOG(@"HistoryClient - didNavigateWithNavigationData - title: %@ - url: %@", title, url);
  65. CFRelease(title);
  66. CFRelease(url);
  67. }
  68. static void didPerformClientRedirect(WKContextRef context, WKPageRef page, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef frame, const void *clientInfo)
  69. {
  70. CFURLRef cfSourceURL = WKURLCopyCFURL(0, sourceURL);
  71. CFURLRef cfDestinationURL = WKURLCopyCFURL(0, destinationURL);
  72. LOG(@"HistoryClient - didPerformClientRedirect - sourceURL: %@ - destinationURL: %@", cfSourceURL, cfDestinationURL);
  73. CFRelease(cfSourceURL);
  74. CFRelease(cfDestinationURL);
  75. }
  76. static void didPerformServerRedirect(WKContextRef context, WKPageRef page, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef frame, const void *clientInfo)
  77. {
  78. CFURLRef cfSourceURL = WKURLCopyCFURL(0, sourceURL);
  79. CFURLRef cfDestinationURL = WKURLCopyCFURL(0, destinationURL);
  80. LOG(@"HistoryClient - didPerformServerRedirect - sourceURL: %@ - destinationURL: %@", cfSourceURL, cfDestinationURL);
  81. CFRelease(cfSourceURL);
  82. CFRelease(cfDestinationURL);
  83. }
  84. static void didUpdateHistoryTitle(WKContextRef context, WKPageRef page, WKStringRef title, WKURLRef URL, WKFrameRef frame, const void *clientInfo)
  85. {
  86. CFStringRef cfTitle = WKStringCopyCFString(0, title);
  87. CFURLRef cfURL = WKURLCopyCFURL(0, URL);
  88. LOG(@"HistoryClient - didUpdateHistoryTitle - title: %@ - URL: %@", cfTitle, cfURL);
  89. CFRelease(cfTitle);
  90. CFRelease(cfURL);
  91. }
  92. static void populateVisitedLinks(WKContextRef context, const void *clientInfo)
  93. {
  94. LOG(@"HistoryClient - populateVisitedLinks");
  95. }
  96. - (id)init
  97. {
  98. self = [super init];
  99. if (self) {
  100. WKContextHistoryClient historyClient = {
  101. kWKContextHistoryClientCurrentVersion,
  102. self,
  103. didNavigateWithNavigationData,
  104. didPerformClientRedirect,
  105. didPerformServerRedirect,
  106. didUpdateHistoryTitle,
  107. populateVisitedLinks
  108. };
  109. CFStringRef bundlePathCF = (CFStringRef)[[NSBundle mainBundle] pathForAuxiliaryExecutable:@"WebBundle.bundle"];
  110. WKStringRef bundlePath = WKStringCreateWithCFString(bundlePathCF);
  111. _processContext = WKContextCreateWithInjectedBundlePath(bundlePath);
  112. WKContextInjectedBundleClient bundleClient = {
  113. kWKContextInjectedBundleClientCurrentVersion,
  114. 0, /* clientInfo */
  115. didReceiveMessageFromInjectedBundle,
  116. 0, /* didReceiveSynchronousMessageFromInjectedBundle */
  117. 0 /* getInjectedBundleInitializationUserData */
  118. };
  119. WKContextSetInjectedBundleClient(_processContext, &bundleClient);
  120. WKContextSetHistoryClient(_processContext, &historyClient);
  121. WKContextSetCacheModel(_processContext, kWKCacheModelPrimaryWebBrowser);
  122. WKRelease(bundlePath);
  123. WKStringRef pageGroupIdentifier = WKStringCreateWithCFString(CFSTR("MiniBrowser"));
  124. _pageGroup = WKPageGroupCreateWithIdentifier(pageGroupIdentifier);
  125. WKRelease(pageGroupIdentifier);
  126. _browserWindows = [[NSMutableSet alloc] init];
  127. }
  128. return self;
  129. }
  130. - (IBAction)newWindow:(id)sender
  131. {
  132. BrowserWindowController *controller = nil;
  133. if (![sender respondsToSelector:@selector(tag)] || [sender tag] == WebKit1NewWindowTag)
  134. controller = [[WK1BrowserWindowController alloc] initWithWindowNibName:@"BrowserWindow"];
  135. else if ([sender tag] == WebKit2NewWindowTag)
  136. controller = [[WK2BrowserWindowController alloc] initWithContext:_processContext pageGroup:_pageGroup];
  137. if (!controller)
  138. return;
  139. [[controller window] makeKeyAndOrderFront:sender];
  140. [_browserWindows addObject:[controller window]];
  141. [controller loadURLString:defaultURL];
  142. }
  143. - (void)browserWindowWillClose:(NSWindow *)window
  144. {
  145. [_browserWindows removeObject:window];
  146. }
  147. - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
  148. {
  149. [self newWindow:self];
  150. }
  151. - (void)applicationWillTerminate:(NSNotification *)notification
  152. {
  153. for (NSWindow* window in _browserWindows) {
  154. id delegate = [window delegate];
  155. assert([delegate isKindOfClass:[BrowserWindowController class]]);
  156. BrowserWindowController *controller = (BrowserWindowController *)delegate;
  157. [controller applicationTerminating];
  158. }
  159. WKRelease(_processContext);
  160. _processContext = 0;
  161. }
  162. - (BrowserWindowController *)frontmostBrowserWindowController
  163. {
  164. NSArray* windows = [NSApp windows];
  165. for (NSWindow* window in windows) {
  166. id delegate = [window delegate];
  167. assert([delegate isKindOfClass:[BrowserWindowController class]]);
  168. BrowserWindowController *controller = (BrowserWindowController *)delegate;
  169. assert([_browserWindows containsObject:[controller window]]);
  170. return controller;
  171. }
  172. return 0;
  173. }
  174. - (IBAction)openDocument:(id)sender
  175. {
  176. NSOpenPanel *openPanel = [[NSOpenPanel openPanel] retain];
  177. [openPanel beginForDirectory:nil
  178. file:nil
  179. types:nil
  180. modelessDelegate:self
  181. didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
  182. contextInfo:0];
  183. }
  184. - (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
  185. {
  186. [sheet autorelease];
  187. if (returnCode != NSOKButton || ![[sheet filenames] count])
  188. return;
  189. NSString* filePath = [[sheet filenames] objectAtIndex:0];
  190. BrowserWindowController *controller = [self frontmostBrowserWindowController];
  191. if (!controller) {
  192. controller = [[WK2BrowserWindowController alloc] initWithContext:_processContext pageGroup:_pageGroup]; // FIXME: add a way to open in WK1 also.
  193. [[controller window] makeKeyAndOrderFront:self];
  194. }
  195. [controller loadURLString:[[NSURL fileURLWithPath:filePath] absoluteString]];
  196. }
  197. @end