1d2f1af296e24be2bf4da25e3c4bff0f44a3a54f
[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     layoutTestContoller = new LayoutTestController();
98     return [super init];
99 }
100
101 - (void)dealloc
102 {
103     delete layoutTestContoller;
104     [super dealloc];
105 }
106
107 // Exec messages in the work queue until they're all done, or one of them starts a new load
108 - (void)processWork:(id)dummy
109 {
110     // quit doing work once a load is in progress
111     while (WorkQueue::shared()->count() > 0 && !topLoadingFrame) {
112         WorkQueueItem* item = WorkQueue::shared()->dequeue();
113         ASSERT(item);
114         item->invoke();
115     }
116     
117     // if we didn't start a new load, then we finished all the commands, so we're ready to dump state
118     if (!topLoadingFrame && !waitToDump)
119         dump();
120 }
121
122 - (void)webView:(WebView *)c locationChangeDone:(NSError *)error forDataSource:(WebDataSource *)dataSource
123 {
124     if ([dataSource webFrame] == topLoadingFrame) {
125         topLoadingFrame = nil;
126         WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
127         if (!waitToDump) {
128             if (WorkQueue::shared()->count())
129                 [self performSelector:@selector(processWork:) withObject:nil afterDelay:0];
130             else
131                 dump();
132         }
133     }
134 }
135
136 - (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame
137 {
138     if (shouldDumpFrameLoadCallbacks && !done) {
139         NSString *string = [NSString stringWithFormat:@"%@ - didStartProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
140         printf ("%s\n", [string UTF8String]);
141     }
142     
143     ASSERT([frame provisionalDataSource]);
144     // Make sure we only set this once per test.  If it gets cleared, and then set again, we might
145     // end up doing two dumps for one test.
146     if (!topLoadingFrame && !done)
147         topLoadingFrame = frame;
148 }
149
150 - (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame
151 {
152     if (shouldDumpFrameLoadCallbacks && !done) {
153         NSString *string = [NSString stringWithFormat:@"%@ - didCommitLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
154         printf ("%s\n", [string UTF8String]);
155     }
156     
157     ASSERT(![frame provisionalDataSource]);
158     ASSERT([frame dataSource]);
159     
160     windowIsKey = YES;
161     NSView *documentView = [[mainFrame frameView] documentView];
162     [[[mainFrame webView] window] makeFirstResponder:documentView];
163     if ([documentView isKindOfClass:[WebHTMLView class]])
164         [(WebHTMLView *)documentView _updateActiveState];
165 }
166
167 - (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
168 {
169     if (shouldDumpFrameLoadCallbacks && !done) {
170         NSString *string = [NSString stringWithFormat:@"%@ - didFailProvisionalLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
171         printf ("%s\n", [string UTF8String]);
172     }
173
174     if ([error domain] == NSURLErrorDomain && [error code] == NSURLErrorServerCertificateHasUnknownRoot) {
175         NSURL *failedURL = [[error userInfo] objectForKey:@"NSErrorFailingURLKey"];
176         [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[failedURL _web_hostString]];
177         [frame loadRequest:[[[[frame provisionalDataSource] request] mutableCopy] autorelease]];
178         return;
179     }
180     
181     ASSERT([frame provisionalDataSource]);
182     [self webView:sender locationChangeDone:error forDataSource:[frame provisionalDataSource]];
183 }
184
185 - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
186 {
187     ASSERT([frame dataSource]);
188     ASSERT(frame == [[frame dataSource] webFrame]);
189     
190     if (shouldDumpFrameLoadCallbacks && !done) {
191         NSString *string = [NSString stringWithFormat:@"%@ - didFinishLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
192         printf ("%s\n", [string UTF8String]);
193     }
194     
195     // FIXME: This call to displayIfNeeded can be removed when <rdar://problem/5092361> is fixed.
196     // After that is fixed, we will reenable painting after WebCore is done loading the document, 
197     // and this call will no longer be needed.
198     if ([[sender mainFrame] isEqual:frame])
199         [sender displayIfNeeded];
200     [self webView:sender locationChangeDone:nil forDataSource:[frame dataSource]];
201     [navigationController webView:sender didFinishLoadForFrame:frame];
202 }
203
204 - (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame;
205 {
206     if (shouldDumpFrameLoadCallbacks && !done) {
207         NSString *string = [NSString stringWithFormat:@"%@ - didFailLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
208         printf ("%s\n", [string UTF8String]);
209     }
210     
211     ASSERT(![frame provisionalDataSource]);
212     ASSERT([frame dataSource]);
213     
214     [self webView:sender locationChangeDone:error forDataSource:[frame dataSource]];    
215 }
216
217 - (void)webView:(WebView *)webView windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject;
218 {
219     if (shouldDumpFrameLoadCallbacks && !done) {
220         NSString *string = [NSString stringWithFormat:@"?? - windowScriptObjectAvailable"];
221         printf ("%s\n", [string UTF8String]);
222     }
223     
224     ASSERT_NOT_REACHED();
225 }
226
227 - (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)obj forFrame:(WebFrame *)frame
228 {
229     if (shouldDumpFrameLoadCallbacks && !done) {
230         NSString *string = [NSString stringWithFormat:@"%@ - didClearWindowObjectForFrame", [frame _drt_descriptionSuitableForTestResult]];
231         printf ("%s\n", [string UTF8String]);
232     }
233         
234     ASSERT(obj == [frame windowObject]);
235     ASSERT([obj JSObject] == JSContextGetGlobalObject([frame globalContext]));
236
237     // Make New-Style LayoutTestController
238     JSContextRef context = [frame globalContext];
239     JSObjectRef globalObject = JSContextGetGlobalObject(context);
240     JSValueRef exception = 0;
241     layoutTestContoller->makeWindowObject(context, globalObject, &exception);
242     ASSERT(!exception);
243
244     // Make Old-Style controllers
245     EventSendingController *esc = [[EventSendingController alloc] init];
246     [obj setValue:esc forKey:@"eventSender"];
247     [esc release];
248     
249     TextInputController *tic = [[TextInputController alloc] initWithWebView:sender];
250     [obj setValue:tic forKey:@"textInputController"];
251     [tic release];
252     
253     AppleScriptController *asc = [[AppleScriptController alloc] initWithWebView:sender];
254     [obj setValue:asc forKey:@"appleScriptController"];
255     [asc release];
256     
257     GCController *gcc = [[GCController alloc] init];
258     [obj setValue:gcc forKey:@"GCController"];
259     [gcc release];
260
261     ObjCController *occ = [[ObjCController alloc] init];
262     [obj setValue:occ forKey:@"objCController"];
263     [occ release];
264
265     [obj setValue:navigationController forKey:@"navigationController"];
266     
267     ObjCPlugin *plugin = [[ObjCPlugin alloc] init];
268     [obj setValue:plugin forKey:@"objCPlugin"];
269     [plugin release];
270     
271     ObjCPluginFunction *pluginFunction = [[ObjCPluginFunction alloc] init];
272     [obj setValue:pluginFunction forKey:@"objCPluginFunction"];
273     [pluginFunction release];
274 }
275
276 - (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
277 {
278     if (shouldDumpFrameLoadCallbacks && !done) {
279         NSString *string = [NSString stringWithFormat:@"%@ - didReceiveTitle: %@", [frame _drt_descriptionSuitableForTestResult], title];
280         printf ("%s\n", [string UTF8String]);
281     }
282     
283     if (dumpTitleChanges)
284         printf("TITLE CHANGED: %s\n", [title UTF8String]);
285 }
286
287 - (void)webView:(WebView *)sender didReceiveServerRedirectForProvisionalLoadForFrame:(WebFrame *)frame
288 {
289     if (shouldDumpFrameLoadCallbacks && !done) {
290         NSString *string = [NSString stringWithFormat:@"%@ - didReceiveServerRedirectForProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
291         printf ("%s\n", [string UTF8String]);
292     }
293 }
294
295 - (void)webView:(WebView *)sender didReceiveIcon:(NSImage *)image forFrame:(WebFrame *)frame
296 {
297     if (shouldDumpFrameLoadCallbacks && !done) {
298         NSString *string = [NSString stringWithFormat:@"%@ - didReceiveIconForFrame", [frame _drt_descriptionSuitableForTestResult]];
299         printf ("%s\n", [string UTF8String]);
300     }
301 }
302
303 - (void)webView:(WebView *)sender didChangeLocationWithinPageForFrame:(WebFrame *)frame
304 {
305     if (shouldDumpFrameLoadCallbacks && !done) {
306         NSString *string = [NSString stringWithFormat:@"%@ - didChangeLocationWithinPageForFrame", [frame _drt_descriptionSuitableForTestResult]];
307         printf ("%s\n", [string UTF8String]);
308     }
309 }
310
311 - (void)webView:(WebView *)sender willPerformClientRedirectToURL:(NSURL *)URL delay:(NSTimeInterval)seconds fireDate:(NSDate *)date forFrame:(WebFrame *)frame
312 {
313     if (shouldDumpFrameLoadCallbacks && !done) {
314         NSString *string = [NSString stringWithFormat:@"%@ - willPerformClientRedirectToURL: %@ ", [frame _drt_descriptionSuitableForTestResult], [URL _drt_descriptionSuitableForTestResult]];
315         printf ("%s\n", [string UTF8String]);
316     }
317 }
318
319 - (void)webView:(WebView *)sender didCancelClientRedirectForFrame:(WebFrame *)frame
320 {
321     if (shouldDumpFrameLoadCallbacks && !done) {
322         NSString *string = [NSString stringWithFormat:@"%@ - didCancelClientRedirectForFrame", [frame _drt_descriptionSuitableForTestResult]];
323         printf ("%s\n", [string UTF8String]);
324     }
325 }
326
327 - (void)webView:(WebView *)sender willCloseFrame:(WebFrame *)frame;
328 {
329     if (shouldDumpFrameLoadCallbacks && !done) {
330         NSString *string = [NSString stringWithFormat:@"%@ - willCloseFrame", [frame _drt_descriptionSuitableForTestResult]];
331         printf ("%s\n", [string UTF8String]);
332     }
333 }
334
335 - (void)webView:(WebView *)sender didFinishDocumentLoadForFrame:(WebFrame *)frame;
336 {
337     if (shouldDumpFrameLoadCallbacks && !done) {
338         NSString *string = [NSString stringWithFormat:@"%@ - didFinishDocumentLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
339         printf ("%s\n", [string UTF8String]);
340     }
341 }
342
343 - (void)webView:(WebView *)sender didHandleOnloadEventsForFrame:(WebFrame *)frame;
344 {
345     if (shouldDumpFrameLoadCallbacks && !done) {
346         NSString *string = [NSString stringWithFormat:@"%@ - didHandleOnloadEventsForFrame", [frame _drt_descriptionSuitableForTestResult]];
347         printf ("%s\n", [string UTF8String]);
348     }
349 }
350
351 @end