Clean up ChunkedUpdateDrawingAreaProxy
[WebKit-https.git] / Tools / DumpRenderTree / mac / 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 "config.h"
30 #import "DumpRenderTree.h"
31 #import "FrameLoadDelegate.h"
32
33 #import "AccessibilityController.h"
34 #import "AppleScriptController.h"
35 #import "EventSendingController.h"
36 #import "GCController.h"
37 #import "LayoutTestController.h"
38 #import "NavigationController.h"
39 #import "ObjCController.h"
40 #import "ObjCPlugin.h"
41 #import "ObjCPluginFunction.h"
42 #import "PlainTextController.h"
43 #import "TextInputController.h"
44 #import "WorkQueue.h"
45 #import "WorkQueueItem.h"
46 #import <JavaScriptCore/JavaScriptCore.h>
47 #import <WebKit/WebFramePrivate.h>
48 #import <WebKit/WebHTMLViewPrivate.h>
49 #import <WebKit/WebKit.h>
50 #import <WebKit/WebNSURLExtras.h>
51 #import <WebKit/WebScriptWorld.h>
52 #import <WebKit/WebSecurityOriginPrivate.h>
53 #import <WebKit/WebViewPrivate.h>
54 #import <wtf/Assertions.h>
55
56 @interface NSURL (DRTExtras)
57 - (NSString *)_drt_descriptionSuitableForTestResult;
58 @end
59
60 @interface NSError (DRTExtras)
61 - (NSString *)_drt_descriptionSuitableForTestResult;
62 @end
63
64 @interface NSURLResponse (DRTExtras)
65 - (NSString *)_drt_descriptionSuitableForTestResult;
66 @end
67
68 @interface NSURLRequest (DRTExtras)
69 - (NSString *)_drt_descriptionSuitableForTestResult;
70 @end
71
72 @interface WebFrame (DRTExtras)
73 - (NSString *)_drt_descriptionSuitableForTestResult;
74 @end
75
76 @implementation WebFrame (DRTExtras)
77 - (NSString *)_drt_descriptionSuitableForTestResult
78 {
79     BOOL isMainFrame = (self == [[self webView] mainFrame]);
80     NSString *name = [self name];
81     if (isMainFrame) {
82         if ([name length])
83             return [NSString stringWithFormat:@"main frame \"%@\"", name];
84         else
85             return @"main frame";
86     } else {
87         if (name)
88             return [NSString stringWithFormat:@"frame \"%@\"", name];
89         else
90             return @"frame (anonymous)";
91     }
92 }
93
94 - (NSString *)_drt_printFrameUserGestureStatus
95 {
96     BOOL isUserGesture = [[self webView] _isProcessingUserGesture];
97     return [NSString stringWithFormat:@"Frame with user gesture \"%@\"", isUserGesture ? @"true" : @"false"];
98 }
99 @end
100
101 @implementation FrameLoadDelegate
102
103 - (id)init
104 {
105     if ((self = [super init])) {
106         gcController = new GCController;
107         accessibilityController = new AccessibilityController;
108     }
109     return self;
110 }
111
112 - (void)dealloc
113 {
114     delete gcController;
115     delete accessibilityController;
116     [super dealloc];
117 }
118
119 // Exec messages in the work queue until they're all done, or one of them starts a new load
120 - (void)processWork:(id)dummy
121 {
122     // if another load started, then wait for it to complete.
123     if (topLoadingFrame)
124         return;
125
126     // if we finish all the commands, we're ready to dump state
127     if (WorkQueue::shared()->processWork() && !gLayoutTestController->waitToDump())
128         dump();
129 }
130
131 - (void)resetToConsistentState
132 {
133     accessibilityController->resetToConsistentState();
134 }
135
136 - (void)webView:(WebView *)c locationChangeDone:(NSError *)error forDataSource:(WebDataSource *)dataSource
137 {
138     if ([dataSource webFrame] == topLoadingFrame) {
139         topLoadingFrame = nil;
140         WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
141         if (!gLayoutTestController->waitToDump()) {
142             if (WorkQueue::shared()->count())
143                 [self performSelector:@selector(processWork:) withObject:nil afterDelay:0];
144             else
145                 dump();
146         }
147     }
148 }
149
150 - (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame
151 {
152     if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
153         NSString *string = [NSString stringWithFormat:@"%@ - didStartProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
154         printf ("%s\n", [string UTF8String]);
155     }
156
157     if (!done && gLayoutTestController->dumpUserGestureInFrameLoadCallbacks()) {
158         NSString *string = [NSString stringWithFormat:@"%@ - in didStartProvisionalLoadForFrame", [frame _drt_printFrameUserGestureStatus]];
159         printf ("%s\n", [string UTF8String]);
160     }
161
162     ASSERT([frame provisionalDataSource]);
163     // Make sure we only set this once per test.  If it gets cleared, and then set again, we might
164     // end up doing two dumps for one test.
165     if (!topLoadingFrame && !done)
166         topLoadingFrame = frame;
167
168     if (!done && gLayoutTestController->stopProvisionalFrameLoads()) {
169         NSString *string = [NSString stringWithFormat:@"%@ - stopping load in didStartProvisionalLoadForFrame callback", [frame _drt_descriptionSuitableForTestResult]];
170         printf ("%s\n", [string UTF8String]);
171         [frame stopLoading];
172     }
173 }
174
175 - (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame
176 {
177     if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
178         NSString *string = [NSString stringWithFormat:@"%@ - didCommitLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
179         printf ("%s\n", [string UTF8String]);
180     }
181
182     ASSERT(![frame provisionalDataSource]);
183     ASSERT([frame dataSource]);
184     
185     gLayoutTestController->setWindowIsKey(true);
186     NSView *documentView = [[mainFrame frameView] documentView];
187     [[[mainFrame webView] window] makeFirstResponder:documentView];
188 }
189
190 - (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
191 {
192     if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
193         NSString *string = [NSString stringWithFormat:@"%@ - didFailProvisionalLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
194         printf("%s\n", [string UTF8String]);
195     }
196
197     if ([error domain] == NSURLErrorDomain && ([error code] == NSURLErrorServerCertificateHasUnknownRoot || [error code] == NSURLErrorServerCertificateUntrusted)) {
198         // <http://webkit.org/b/31200> In order to prevent extra frame load delegate logging being generated if the first test to use SSL
199         // is set to log frame load delegate calls we ignore SSL certificate errors on localhost and 127.0.0.1 from within dumpRenderTree.
200         // Those are the only hosts that we use SSL with at present.  If we hit this code path then we've found another host that we need
201         // to apply the workaround to.
202         ASSERT_NOT_REACHED();
203         return;
204     }
205
206     ASSERT([frame provisionalDataSource]);
207     [self webView:sender locationChangeDone:error forDataSource:[frame provisionalDataSource]];
208 }
209
210 - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
211 {
212     ASSERT([frame dataSource]);
213     ASSERT(frame == [[frame dataSource] webFrame]);
214     
215     if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
216         NSString *string = [NSString stringWithFormat:@"%@ - didFinishLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
217         printf ("%s\n", [string UTF8String]);
218     }
219
220     // FIXME: This call to displayIfNeeded can be removed when <rdar://problem/5092361> is fixed.
221     // After that is fixed, we will reenable painting after WebCore is done loading the document, 
222     // and this call will no longer be needed.
223     if ([[sender mainFrame] isEqual:frame])
224         [sender displayIfNeeded];
225     [self webView:sender locationChangeDone:nil forDataSource:[frame dataSource]];
226     [gNavigationController webView:sender didFinishLoadForFrame:frame];
227 }
228
229 - (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
230 {
231     if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
232         NSString *string = [NSString stringWithFormat:@"%@ - didFailLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
233         printf ("%s\n", [string UTF8String]);
234     }
235
236     ASSERT(![frame provisionalDataSource]);
237     ASSERT([frame dataSource]);
238     
239     [self webView:sender locationChangeDone:error forDataSource:[frame dataSource]];    
240 }
241
242 - (void)webView:(WebView *)webView windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject
243 {
244     if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
245         NSString *string = [NSString stringWithFormat:@"?? - windowScriptObjectAvailable"];
246         printf ("%s\n", [string UTF8String]);
247     }
248
249     ASSERT_NOT_REACHED();
250 }
251
252 - (void)didClearWindowObjectInStandardWorldForFrame:(WebFrame *)frame
253 {
254     // Make New-Style LayoutTestController
255     JSContextRef context = [frame globalContext];
256     JSObjectRef globalObject = JSContextGetGlobalObject(context);
257     JSValueRef exception = 0;
258
259     ASSERT(gLayoutTestController);
260     gLayoutTestController->makeWindowObject(context, globalObject, &exception);
261     ASSERT(!exception);
262
263     gcController->makeWindowObject(context, globalObject, &exception);
264     ASSERT(!exception);
265
266     accessibilityController->makeWindowObject(context, globalObject, &exception);
267     ASSERT(!exception);
268
269     // Make Old-Style controllers
270
271     WebView *webView = [frame webView];
272     WebScriptObject *obj = [frame windowObject];
273     AppleScriptController *asc = [[AppleScriptController alloc] initWithWebView:webView];
274     [obj setValue:asc forKey:@"appleScriptController"];
275     [asc release];
276
277     EventSendingController *esc = [[EventSendingController alloc] init];
278     [obj setValue:esc forKey:@"eventSender"];
279     [esc release];
280     
281     [obj setValue:gNavigationController forKey:@"navigationController"];
282     
283     ObjCController *occ = [[ObjCController alloc] init];
284     [obj setValue:occ forKey:@"objCController"];
285     [occ release];
286
287     ObjCPlugin *plugin = [[ObjCPlugin alloc] init];
288     [obj setValue:plugin forKey:@"objCPlugin"];
289     [plugin release];
290     
291     ObjCPluginFunction *pluginFunction = [[ObjCPluginFunction alloc] init];
292     [obj setValue:pluginFunction forKey:@"objCPluginFunction"];
293     [pluginFunction release];
294
295     [obj setValue:[PlainTextController sharedPlainTextController] forKey:@"plainText"];
296
297     TextInputController *tic = [[TextInputController alloc] initWithWebView:webView];
298     [obj setValue:tic forKey:@"textInputController"];
299     [tic release];
300 }
301
302 - (void)didClearWindowObjectForFrame:(WebFrame *)frame inIsolatedWorld:(WebScriptWorld *)world
303 {
304     JSGlobalContextRef ctx = [frame _globalContextForScriptWorld:world];
305     if (!ctx)
306         return;
307
308     JSObjectRef globalObject = JSContextGetGlobalObject(ctx);
309     if (!globalObject)
310         return;
311
312     JSObjectSetProperty(ctx, globalObject, JSRetainPtr<JSStringRef>(Adopt, JSStringCreateWithUTF8CString("__worldID")).get(), JSValueMakeNumber(ctx, worldIDForWorld(world)), kJSPropertyAttributeReadOnly, 0);
313 }
314
315 - (void)webView:(WebView *)sender didClearWindowObjectForFrame:(WebFrame *)frame inScriptWorld:(WebScriptWorld *)world
316 {
317     if (world == [WebScriptWorld standardWorld])
318         [self didClearWindowObjectInStandardWorldForFrame:frame];
319     else
320         [self didClearWindowObjectForFrame:frame inIsolatedWorld:world];
321 }
322
323 - (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
324 {
325     if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
326         NSString *string = [NSString stringWithFormat:@"%@ - didReceiveTitle: %@", [frame _drt_descriptionSuitableForTestResult], title];
327         printf ("%s\n", [string UTF8String]);
328     }
329
330     if (gLayoutTestController->dumpTitleChanges())
331         printf("TITLE CHANGED: %s\n", [title UTF8String]);
332 }
333
334 - (void)webView:(WebView *)sender didReceiveServerRedirectForProvisionalLoadForFrame:(WebFrame *)frame
335 {
336     if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
337         NSString *string = [NSString stringWithFormat:@"%@ - didReceiveServerRedirectForProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
338         printf ("%s\n", [string UTF8String]);
339     }
340 }
341
342 - (void)webView:(WebView *)sender didChangeLocationWithinPageForFrame:(WebFrame *)frame
343 {
344     if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
345         NSString *string = [NSString stringWithFormat:@"%@ - didChangeLocationWithinPageForFrame", [frame _drt_descriptionSuitableForTestResult]];
346         printf ("%s\n", [string UTF8String]);
347     }
348 }
349
350 - (void)webView:(WebView *)sender willPerformClientRedirectToURL:(NSURL *)URL delay:(NSTimeInterval)seconds fireDate:(NSDate *)date forFrame:(WebFrame *)frame
351 {
352     if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
353         NSString *string = [NSString stringWithFormat:@"%@ - willPerformClientRedirectToURL: %@ ", [frame _drt_descriptionSuitableForTestResult], [URL _drt_descriptionSuitableForTestResult]];
354         printf ("%s\n", [string UTF8String]);
355     }
356 }
357
358 - (void)webView:(WebView *)sender didCancelClientRedirectForFrame:(WebFrame *)frame
359 {
360     if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
361         NSString *string = [NSString stringWithFormat:@"%@ - didCancelClientRedirectForFrame", [frame _drt_descriptionSuitableForTestResult]];
362         printf ("%s\n", [string UTF8String]);
363     }
364 }
365
366 - (void)webView:(WebView *)sender didFinishDocumentLoadForFrame:(WebFrame *)frame
367 {
368     if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
369         NSString *string = [NSString stringWithFormat:@"%@ - didFinishDocumentLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
370         printf ("%s\n", [string UTF8String]);
371     } else if (!done) {
372         unsigned pendingFrameUnloadEvents = [frame _pendingFrameUnloadEventCount];
373         if (pendingFrameUnloadEvents) {
374             NSString *string = [NSString stringWithFormat:@"%@ - has %u onunload handler(s)", [frame _drt_descriptionSuitableForTestResult], pendingFrameUnloadEvents];
375             printf ("%s\n", [string UTF8String]);
376         }
377     }
378 }
379
380 - (void)webView:(WebView *)sender didHandleOnloadEventsForFrame:(WebFrame *)frame
381 {
382     if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
383         NSString *string = [NSString stringWithFormat:@"%@ - didHandleOnloadEventsForFrame", [frame _drt_descriptionSuitableForTestResult]];
384         printf ("%s\n", [string UTF8String]);
385     }
386 }
387
388 - (void)webViewDidDisplayInsecureContent:(WebView *)sender
389 {
390     if (!done && gLayoutTestController->dumpFrameLoadCallbacks())
391         printf ("didDisplayInsecureContent\n");
392 }
393
394 - (void)webView:(WebView *)sender didRunInsecureContent:(WebSecurityOrigin *)origin
395 {
396     if (!done && gLayoutTestController->dumpFrameLoadCallbacks())
397         printf ("didRunInsecureContent\n");
398 }
399
400 @end