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 "BrowserWindowController.h"
28 #import <WebKit2/WKPagePrivate.h>
29 #import <WebKit2/WKStringCF.h>
30 #import <WebKit2/WKURLCF.h>
32 @interface BrowserWindowController ()
33 - (void)didStartProgress;
34 - (void)didChangeProgress:(double)value;
35 - (void)didFinishProgress;
36 - (void)didStartProvisionalLoadForFrame:(WKFrameRef)frame;
37 - (void)didCommitLoadForFrame:(WKFrameRef)frame;
38 - (void)didReceiveServerRedirectForProvisionalLoadForFrame:(WKFrameRef)frame;
39 - (void)didFailProvisionalLoadWithErrorForFrame:(WKFrameRef)frame;
40 - (void)didFailLoadWithErrorForFrame:(WKFrameRef)frame;
43 @implementation BrowserWindowController
45 - (id)initWithPageNamespace:(WKPageNamespaceRef)pageNamespace
47 if ((self = [super initWithWindowNibName:@"BrowserWindow"]))
48 _pageNamespace = WKRetain(pageNamespace);
55 assert(!_pageNamespace);
59 - (IBAction)fetch:(id)sender
61 CFURLRef cfURL = CFURLCreateWithString(0, (CFStringRef)[urlText stringValue], 0);
62 WKURLRef url = WKURLCreateWithCFURL(cfURL);
65 WKPageLoadURL(_webView.pageRef, url);
69 - (IBAction)showHideWebView:(id)sender
71 BOOL hidden = ![_webView isHidden];
73 [_webView setHidden:hidden];
76 - (IBAction)removeReinsertWebView:(id)sender
78 if ([_webView window]) {
80 [_webView removeFromSuperview];
82 [containerView addSubview:_webView];
87 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
89 if ([menuItem action] == @selector(showHideWebView:))
90 [menuItem setTitle:[_webView isHidden] ? @"Show Web View" : @"Hide Web View"];
91 else if ([menuItem action] == @selector(removeReinsertWebView:))
92 [menuItem setTitle:[_webView window] ? @"Remove Web View" : @"Insert Web View"];
96 - (IBAction)reload:(id)sender
98 WKPageReload(_webView.pageRef);
101 - (IBAction)forceRepaint:(id)sender
103 [_webView setNeedsDisplay:YES];
106 - (IBAction)goBack:(id)sender
108 WKPageGoBack(_webView.pageRef);
111 - (IBAction)goForward:(id)sender
113 WKPageGoForward(_webView.pageRef);
116 - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item
118 SEL action = [item action];
120 if (action == @selector(goBack:))
121 return _webView && WKPageCanGoBack(_webView.pageRef);
123 if (action == @selector(goForward:))
124 return _webView && WKPageCanGoForward(_webView.pageRef);
129 - (void)validateToolbar
131 [toolbar validateVisibleItems];
134 - (BOOL)windowShouldClose:(id)sender
136 LOG(@"windowShouldClose");
137 BOOL canCloseImmediately = WKPageTryClose(_webView.pageRef);
138 return canCloseImmediately;
141 - (void)windowWillClose:(NSNotification *)notification
143 WKRelease(_pageNamespace);
147 - (void)applicationTerminating
149 WKPageClose(_webView.pageRef);
150 WKRelease(_webView.pageRef);
153 #pragma mark Loader Client Callbacks
155 static void didStartProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
157 [(BrowserWindowController *)clientInfo didStartProvisionalLoadForFrame:frame];
160 static void didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
162 [(BrowserWindowController *)clientInfo didReceiveServerRedirectForProvisionalLoadForFrame:frame];
165 static void didFailProvisionalLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
167 [(BrowserWindowController *)clientInfo didFailProvisionalLoadWithErrorForFrame:frame];
170 static void didCommitLoadForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
172 [(BrowserWindowController *)clientInfo didCommitLoadForFrame:frame];
175 static void didFinishDocumentLoadForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
177 LOG(@"didFinishDocumentLoadForFrame");
180 static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
182 LOG(@"didFinishLoadForFrame");
185 static void didFailLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
187 [(BrowserWindowController *)clientInfo didFailLoadWithErrorForFrame:frame];
190 static void didReceiveTitleForFrame(WKPageRef page, WKStringRef title, WKFrameRef frame, const void *clientInfo)
192 CFStringRef cfTitle = WKStringCopyCFString(0, title);
193 LOG(@"didReceiveTitleForFrame \"%@\"", (NSString *)cfTitle);
197 static void didFirstLayoutForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
199 LOG(@"didFirstLayoutForFrame");
202 static void didFirstVisuallyNonEmptyLayoutForFrame(WKPageRef page, WKFrameRef frame, const void *clientInfo)
204 LOG(@"didFirstVisuallyNonEmptyLayoutForFrame");
207 static void didStartProgress(WKPageRef page, const void *clientInfo)
209 [(BrowserWindowController *)clientInfo didStartProgress];
212 static void didChangeProgress(WKPageRef page, const void *clientInfo)
214 [(BrowserWindowController *)clientInfo didChangeProgress:WKPageGetEstimatedProgress(page)];
217 static void didFinishProgress(WKPageRef page, const void *clientInfo)
219 [(BrowserWindowController *)clientInfo didFinishProgress];
222 static void didBecomeUnresponsive(WKPageRef page, const void *clientInfo)
224 LOG(@"didBecomeUnresponsive");
227 static void didBecomeResponsive(WKPageRef page, const void *clientInfo)
229 LOG(@"didBecomeResponsive");
232 static void processDidExit(WKPageRef page, const void *clientInfo)
234 LOG(@"processDidExit");
237 static void didChangeBackForwardList(WKPageRef page, const void *clientInfo)
239 [(BrowserWindowController *)clientInfo validateToolbar];
242 #pragma mark Policy Client Callbacks
244 static void decidePolicyForNavigationAction(WKPageRef page, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKURLRef url, WKFrameRef frame, WKFramePolicyListenerRef listener, const void *clientInfo)
246 LOG(@"decidePolicyForNavigationAction");
247 WKFramePolicyListenerUse(listener);
250 static void decidePolicyForNewWindowAction(WKPageRef page, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKURLRef url, WKFrameRef frame, WKFramePolicyListenerRef listener, const void *clientInfo)
252 LOG(@"decidePolicyForNewWindowAction");
253 WKFramePolicyListenerUse(listener);
256 static void decidePolicyForMIMEType(WKPageRef page, WKStringRef MIMEType, WKURLRef url, WKFrameRef frame, WKFramePolicyListenerRef listener, const void *clientInfo)
258 WKFramePolicyListenerUse(listener);
261 #pragma mark UI Client Callbacks
263 static WKPageRef createNewPage(WKPageRef page, const void* clientInfo)
265 LOG(@"createNewPage");
266 BrowserWindowController *controller = [[BrowserWindowController alloc] initWithPageNamespace:WKPageGetPageNamespace(page)];
267 [controller loadWindow];
269 return controller->_webView.pageRef;
272 static void showPage(WKPageRef page, const void *clientInfo)
275 [[(BrowserWindowController *)clientInfo window] orderFront:nil];
278 static void closePage(WKPageRef page, const void *clientInfo)
282 [[(BrowserWindowController *)clientInfo window] close];
286 static void runJavaScriptAlert(WKPageRef page, WKStringRef message, WKFrameRef frame, const void* clientInfo)
288 NSAlert* alert = [[NSAlert alloc] init];
290 WKURLRef wkURL = WKFrameCopyURL(frame);
291 CFURLRef cfURL = WKURLCopyCFURL(0, wkURL);
294 [alert setMessageText:[NSString stringWithFormat:@"JavaScript alert dialog from %@.", [(NSURL *)cfURL absoluteString]]];
297 CFStringRef cfMessage = WKStringCopyCFString(0, message);
298 [alert setInformativeText:(NSString *)cfMessage];
299 CFRelease(cfMessage);
301 [alert addButtonWithTitle:@"OK"];
307 static bool runJavaScriptConfirm(WKPageRef page, WKStringRef message, WKFrameRef frame, const void* clientInfo)
309 NSAlert* alert = [[NSAlert alloc] init];
311 WKURLRef wkURL = WKFrameCopyURL(frame);
312 CFURLRef cfURL = WKURLCopyCFURL(0, wkURL);
315 [alert setMessageText:[NSString stringWithFormat:@"JavaScript confirm dialog from %@.", [(NSURL *)cfURL absoluteString]]];
318 CFStringRef cfMessage = WKStringCopyCFString(0, message);
319 [alert setInformativeText:(NSString *)cfMessage];
320 CFRelease(cfMessage);
322 [alert addButtonWithTitle:@"OK"];
323 [alert addButtonWithTitle:@"Cancel"];
325 NSInteger button = [alert runModal];
328 return button == NSAlertFirstButtonReturn;
331 static WKStringRef runJavaScriptPrompt(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, const void* clientInfo)
333 NSAlert* alert = [[NSAlert alloc] init];
335 WKURLRef wkURL = WKFrameCopyURL(frame);
336 CFURLRef cfURL = WKURLCopyCFURL(0, wkURL);
339 [alert setMessageText:[NSString stringWithFormat:@"JavaScript prompt dialog from %@.", [(NSURL *)cfURL absoluteString]]];
342 CFStringRef cfMessage = WKStringCopyCFString(0, message);
343 [alert setInformativeText:(NSString *)cfMessage];
344 CFRelease(cfMessage);
346 [alert addButtonWithTitle:@"OK"];
347 [alert addButtonWithTitle:@"Cancel"];
349 NSTextField* input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)];
350 CFStringRef cfDefaultValue = WKStringCopyCFString(0, defaultValue);
351 [input setStringValue:(NSString *)cfDefaultValue];
352 CFRelease(cfDefaultValue);
354 [alert setAccessoryView:input];
356 NSInteger button = [alert runModal];
358 NSString* result = nil;
359 if (button == NSAlertFirstButtonReturn) {
360 [input validateEditing];
361 result = [input stringValue];
368 return WKStringCreateWithCFString((CFStringRef)result);
373 _webView = [[WKView alloc] initWithFrame:[containerView frame] pageNamespaceRef:_pageNamespace];
375 [containerView addSubview:_webView];
376 [_webView setFrame:[containerView frame]];
378 [_webView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
380 WKPageLoaderClient loadClient = {
382 self, /* clientInfo */
383 didStartProvisionalLoadForFrame,
384 didReceiveServerRedirectForProvisionalLoadForFrame,
385 didFailProvisionalLoadWithErrorForFrame,
386 didCommitLoadForFrame,
387 didFinishDocumentLoadForFrame,
388 didFinishLoadForFrame,
389 didFailLoadWithErrorForFrame,
390 didReceiveTitleForFrame,
391 didFirstLayoutForFrame,
392 didFirstVisuallyNonEmptyLayoutForFrame,
396 didBecomeUnresponsive,
399 didChangeBackForwardList
401 WKPageSetPageLoaderClient(_webView.pageRef, &loadClient);
403 WKPagePolicyClient policyClient = {
405 self, /* clientInfo */
406 decidePolicyForNavigationAction,
407 decidePolicyForNewWindowAction,
408 decidePolicyForMIMEType
410 WKPageSetPagePolicyClient(_webView.pageRef, &policyClient);
412 WKPageUIClient uiClient = {
414 self, /* clientInfo */
419 runJavaScriptConfirm,
421 0 /* contentsSizeChanged */
423 WKPageSetPageUIClient(_webView.pageRef, &uiClient);
426 - (void)didStartProgress
428 [progressIndicator setDoubleValue:0.0];
429 [progressIndicator setHidden:NO];
432 - (void)didChangeProgress:(double)value
434 [progressIndicator setDoubleValue:value];
437 - (void)didFinishProgress
439 [progressIndicator setHidden:YES];
440 [progressIndicator setDoubleValue:1.0];
443 - (void)updateProvisionalURLForFrame:(WKFrameRef)frame
445 WKURLRef url = WKFrameCopyProvisionalURL(frame);
449 CFURLRef cfSourceURL = WKURLCopyCFURL(0, url);
452 [urlText setStringValue:(NSString*)CFURLGetString(cfSourceURL)];
453 CFRelease(cfSourceURL);
456 - (void)didStartProvisionalLoadForFrame:(WKFrameRef)frame
458 if (!WKFrameIsMainFrame(frame))
461 [self updateProvisionalURLForFrame:frame];
464 - (void)didReceiveServerRedirectForProvisionalLoadForFrame:(WKFrameRef)frame
466 if (!WKFrameIsMainFrame(frame))
469 [self updateProvisionalURLForFrame:frame];
472 - (void)didFailProvisionalLoadWithErrorForFrame:(WKFrameRef)frame
474 if (!WKFrameIsMainFrame(frame))
477 [self updateProvisionalURLForFrame:frame];
480 - (void)didFailLoadWithErrorForFrame:(WKFrameRef)frame
482 if (!WKFrameIsMainFrame(frame))
485 [self updateProvisionalURLForFrame:frame];
488 - (void)didCommitLoadForFrame:(WKFrameRef)frame
492 - (void)loadURLString:(NSString *)urlString
494 // FIXME: We shouldn't have to set the url text here.
495 [urlText setStringValue:urlString];