Rubber stamped by Darin.
[WebKit-https.git] / WebKitTools / DumpRenderTree / FrameLoadDelegate.mm
1 /*
2  * Copyright (C) 2007 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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #import "FrameLoadDelegate.h"
30
31 #import "AppleScriptController.h"
32 #import "DumpRenderTree.h"
33 #import "EventSendingController.h"
34 #import "GCController.h"
35 #import "LayoutTestController.h"
36 #import "NavigationController.h"
37 #import "ObjCController.h"
38 #import "ObjCPlugin.h"
39 #import "ObjCPluginFunction.h"
40 #import "TextInputController.h"
41 #import "WorkQueue.h"
42 #import "WorkQueueItem.h"
43 #import <JavaScriptCore/Assertions.h>
44 #import <JavaScriptCore/JavaScriptCore.h>
45 #import <WebKit/WebFramePrivate.h>
46 #import <WebKit/WebHTMLViewPrivate.h>
47 #import <WebKit/WebKit.h>
48 #import <WebKit/WebNSURLExtras.h>
49
50 @interface NSURLRequest (PrivateThingsWeShouldntReallyUse)
51 +(void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString *)host;
52 @end
53
54 @interface NSURL (DRTExtras)
55 - (NSString *)_drt_descriptionSuitableForTestResult;
56 @end
57
58 @interface NSError (DRTExtras)
59 - (NSString *)_drt_descriptionSuitableForTestResult;
60 @end
61
62 @interface NSURLResponse (DRTExtras)
63 - (NSString *)_drt_descriptionSuitableForTestResult;
64 @end
65
66 @interface NSURLRequest (DRTExtras)
67 - (NSString *)_drt_descriptionSuitableForTestResult;
68 @end
69
70 @interface WebFrame (DRTExtras)
71 - (NSString *)_drt_descriptionSuitableForTestResult;
72 @end
73
74 @implementation WebFrame (DRTExtras)
75 - (NSString *)_drt_descriptionSuitableForTestResult
76 {
77     BOOL isMainFrame = (self == [[self webView] mainFrame]);
78     NSString *name = [self name];
79     if (isMainFrame) {
80         if ([name length])
81             return [NSString stringWithFormat:@"main frame \"%@\"", name];
82         else
83             return @"main frame";
84     } else {
85         if (name)
86             return [NSString stringWithFormat:@"frame \"%@\"", name];
87         else
88             return @"frame (anonymous)";
89     }
90 }
91 @end
92
93 @implementation FrameLoadDelegate
94
95 - (id)init
96 {
97     if ((self = [super init])) {
98         layoutTestContoller = new LayoutTestController;
99         gcController = new GCController;
100     }
101     return self;
102 }
103
104 - (void)dealloc
105 {
106     delete layoutTestContoller;
107     delete gcController;
108     [super dealloc];
109 }
110
111 // Exec messages in the work queue until they're all done, or one of them starts a new load
112 - (void)processWork:(id)dummy
113 {
114     // quit doing work once a load is in progress
115     while (WorkQueue::shared()->count() > 0 && !topLoadingFrame) {
116         WorkQueueItem* item = WorkQueue::shared()->dequeue();
117         ASSERT(item);
118         item->invoke();
119         delete item;
120     }
121     
122     // if we didn't start a new load, then we finished all the commands, so we're ready to dump state
123     if (!topLoadingFrame && !waitToDump)
124         dump();
125 }
126
127 - (void)webView:(WebView *)c locationChangeDone:(NSError *)error forDataSource:(WebDataSource *)dataSource
128 {
129     if ([dataSource webFrame] == topLoadingFrame) {
130         topLoadingFrame = nil;
131         WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
132         if (!waitToDump) {
133             if (WorkQueue::shared()->count())
134                 [self performSelector:@selector(processWork:) withObject:nil afterDelay:0];
135             else
136                 dump();
137         }
138     }
139 }
140
141 - (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame
142 {
143     if (shouldDumpFrameLoadCallbacks && !done) {
144         NSString *string = [NSString stringWithFormat:@"%@ - didStartProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
145         printf ("%s\n", [string UTF8String]);
146     }
147     
148     ASSERT([frame provisionalDataSource]);
149     // Make sure we only set this once per test.  If it gets cleared, and then set again, we might
150     // end up doing two dumps for one test.
151     if (!topLoadingFrame && !done)
152         topLoadingFrame = frame;
153 }
154
155 - (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame
156 {
157     if (shouldDumpFrameLoadCallbacks && !done) {
158         NSString *string = [NSString stringWithFormat:@"%@ - didCommitLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
159         printf ("%s\n", [string UTF8String]);
160     }
161     
162     ASSERT(![frame provisionalDataSource]);
163     ASSERT([frame dataSource]);
164     
165     windowIsKey = YES;
166     NSView *documentView = [[mainFrame frameView] documentView];
167     [[[mainFrame webView] window] makeFirstResponder:documentView];
168     if ([documentView isKindOfClass:[WebHTMLView class]])
169         [(WebHTMLView *)documentView _updateActiveState];
170 }
171
172 - (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
173 {
174     if (shouldDumpFrameLoadCallbacks && !done) {
175         NSString *string = [NSString stringWithFormat:@"%@ - didFailProvisionalLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
176         printf ("%s\n", [string UTF8String]);
177     }
178
179     if ([error domain] == NSURLErrorDomain && [error code] == NSURLErrorServerCertificateHasUnknownRoot) {
180         NSURL *failedURL = [[error userInfo] objectForKey:@"NSErrorFailingURLKey"];
181         [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[failedURL _web_hostString]];
182         [frame loadRequest:[[[[frame provisionalDataSource] request] mutableCopy] autorelease]];
183         return;
184     }
185     
186     ASSERT([frame provisionalDataSource]);
187     [self webView:sender locationChangeDone:error forDataSource:[frame provisionalDataSource]];
188 }
189
190 - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
191 {
192     ASSERT([frame dataSource]);
193     ASSERT(frame == [[frame dataSource] webFrame]);
194     
195     if (shouldDumpFrameLoadCallbacks && !done) {
196         NSString *string = [NSString stringWithFormat:@"%@ - didFinishLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
197         printf ("%s\n", [string UTF8String]);
198     }
199     
200     // FIXME: This call to displayIfNeeded can be removed when <rdar://problem/5092361> is fixed.
201     // After that is fixed, we will reenable painting after WebCore is done loading the document, 
202     // and this call will no longer be needed.
203     if ([[sender mainFrame] isEqual:frame])
204         [sender displayIfNeeded];
205     [self webView:sender locationChangeDone:nil forDataSource:[frame dataSource]];
206     [navigationController webView:sender didFinishLoadForFrame:frame];
207 }
208
209 - (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame;
210 {
211     if (shouldDumpFrameLoadCallbacks && !done) {
212         NSString *string = [NSString stringWithFormat:@"%@ - didFailLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
213         printf ("%s\n", [string UTF8String]);
214     }
215     
216     ASSERT(![frame provisionalDataSource]);
217     ASSERT([frame dataSource]);
218     
219     [self webView:sender locationChangeDone:error forDataSource:[frame dataSource]];    
220 }
221
222 - (void)webView:(WebView *)webView windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject;
223 {
224     if (shouldDumpFrameLoadCallbacks && !done) {
225         NSString *string = [NSString stringWithFormat:@"?? - windowScriptObjectAvailable"];
226         printf ("%s\n", [string UTF8String]);
227     }
228     
229     ASSERT_NOT_REACHED();
230 }
231
232 - (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)obj forFrame:(WebFrame *)frame
233 {
234     if (shouldDumpFrameLoadCallbacks && !done) {
235         NSString *string = [NSString stringWithFormat:@"%@ - didClearWindowObjectForFrame", [frame _drt_descriptionSuitableForTestResult]];
236         printf ("%s\n", [string UTF8String]);
237     }
238         
239     ASSERT(obj == [frame windowObject]);
240     ASSERT([obj JSObject] == JSContextGetGlobalObject([frame globalContext]));
241
242     // Make New-Style LayoutTestController
243     JSContextRef context = [frame globalContext];
244     JSObjectRef globalObject = JSContextGetGlobalObject(context);
245     JSValueRef exception = 0;
246
247     layoutTestContoller->makeWindowObject(context, globalObject, &exception);
248     ASSERT(!exception);
249
250     gcController->makeWindowObject(context, globalObject, &exception);
251     ASSERT(!exception);
252
253     // Make Old-Style controllers
254     EventSendingController *esc = [[EventSendingController alloc] init];
255     [obj setValue:esc forKey:@"eventSender"];
256     [esc release];
257     
258     TextInputController *tic = [[TextInputController alloc] initWithWebView:sender];
259     [obj setValue:tic forKey:@"textInputController"];
260     [tic release];
261     
262     AppleScriptController *asc = [[AppleScriptController alloc] initWithWebView:sender];
263     [obj setValue:asc forKey:@"appleScriptController"];
264     [asc release];
265
266     ObjCController *occ = [[ObjCController alloc] init];
267     [obj setValue:occ forKey:@"objCController"];
268     [occ release];
269
270     [obj setValue:navigationController forKey:@"navigationController"];
271     
272     ObjCPlugin *plugin = [[ObjCPlugin alloc] init];
273     [obj setValue:plugin forKey:@"objCPlugin"];
274     [plugin release];
275     
276     ObjCPluginFunction *pluginFunction = [[ObjCPluginFunction alloc] init];
277     [obj setValue:pluginFunction forKey:@"objCPluginFunction"];
278     [pluginFunction release];
279 }
280
281 - (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
282 {
283     if (shouldDumpFrameLoadCallbacks && !done) {
284         NSString *string = [NSString stringWithFormat:@"%@ - didReceiveTitle: %@", [frame _drt_descriptionSuitableForTestResult], title];
285         printf ("%s\n", [string UTF8String]);
286     }
287     
288     if (dumpTitleChanges)
289         printf("TITLE CHANGED: %s\n", [title UTF8String]);
290 }
291
292 - (void)webView:(WebView *)sender didReceiveServerRedirectForProvisionalLoadForFrame:(WebFrame *)frame
293 {
294     if (shouldDumpFrameLoadCallbacks && !done) {
295         NSString *string = [NSString stringWithFormat:@"%@ - didReceiveServerRedirectForProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
296         printf ("%s\n", [string UTF8String]);
297     }
298 }
299
300 - (void)webView:(WebView *)sender didReceiveIcon:(NSImage *)image forFrame:(WebFrame *)frame
301 {
302     if (shouldDumpFrameLoadCallbacks && !done) {
303         NSString *string = [NSString stringWithFormat:@"%@ - didReceiveIconForFrame", [frame _drt_descriptionSuitableForTestResult]];
304         printf ("%s\n", [string UTF8String]);
305     }
306 }
307
308 - (void)webView:(WebView *)sender didChangeLocationWithinPageForFrame:(WebFrame *)frame
309 {
310     if (shouldDumpFrameLoadCallbacks && !done) {
311         NSString *string = [NSString stringWithFormat:@"%@ - didChangeLocationWithinPageForFrame", [frame _drt_descriptionSuitableForTestResult]];
312         printf ("%s\n", [string UTF8String]);
313     }
314 }
315
316 - (void)webView:(WebView *)sender willPerformClientRedirectToURL:(NSURL *)URL delay:(NSTimeInterval)seconds fireDate:(NSDate *)date forFrame:(WebFrame *)frame
317 {
318     if (shouldDumpFrameLoadCallbacks && !done) {
319         NSString *string = [NSString stringWithFormat:@"%@ - willPerformClientRedirectToURL: %@ ", [frame _drt_descriptionSuitableForTestResult], [URL _drt_descriptionSuitableForTestResult]];
320         printf ("%s\n", [string UTF8String]);
321     }
322 }
323
324 - (void)webView:(WebView *)sender didCancelClientRedirectForFrame:(WebFrame *)frame
325 {
326     if (shouldDumpFrameLoadCallbacks && !done) {
327         NSString *string = [NSString stringWithFormat:@"%@ - didCancelClientRedirectForFrame", [frame _drt_descriptionSuitableForTestResult]];
328         printf ("%s\n", [string UTF8String]);
329     }
330 }
331
332 - (void)webView:(WebView *)sender willCloseFrame:(WebFrame *)frame;
333 {
334     if (shouldDumpFrameLoadCallbacks && !done) {
335         NSString *string = [NSString stringWithFormat:@"%@ - willCloseFrame", [frame _drt_descriptionSuitableForTestResult]];
336         printf ("%s\n", [string UTF8String]);
337     }
338 }
339
340 - (void)webView:(WebView *)sender didFinishDocumentLoadForFrame:(WebFrame *)frame;
341 {
342     if (shouldDumpFrameLoadCallbacks && !done) {
343         NSString *string = [NSString stringWithFormat:@"%@ - didFinishDocumentLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
344         printf ("%s\n", [string UTF8String]);
345     }
346 }
347
348 - (void)webView:(WebView *)sender didHandleOnloadEventsForFrame:(WebFrame *)frame;
349 {
350     if (shouldDumpFrameLoadCallbacks && !done) {
351         NSString *string = [NSString stringWithFormat:@"%@ - didHandleOnloadEventsForFrame", [frame _drt_descriptionSuitableForTestResult]];
352         printf ("%s\n", [string UTF8String]);
353     }
354 }
355
356 @end