• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <wtf/Assertions.h>
52
53@interface NSURLRequest (PrivateThingsWeShouldntReallyUse)
54+(void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString *)host;
55@end
56
57@interface NSURL (DRTExtras)
58- (NSString *)_drt_descriptionSuitableForTestResult;
59@end
60
61@interface NSError (DRTExtras)
62- (NSString *)_drt_descriptionSuitableForTestResult;
63@end
64
65@interface NSURLResponse (DRTExtras)
66- (NSString *)_drt_descriptionSuitableForTestResult;
67@end
68
69@interface NSURLRequest (DRTExtras)
70- (NSString *)_drt_descriptionSuitableForTestResult;
71@end
72
73@interface WebFrame (DRTExtras)
74- (NSString *)_drt_descriptionSuitableForTestResult;
75@end
76
77@implementation WebFrame (DRTExtras)
78- (NSString *)_drt_descriptionSuitableForTestResult
79{
80    BOOL isMainFrame = (self == [[self webView] mainFrame]);
81    NSString *name = [self name];
82    if (isMainFrame) {
83        if ([name length])
84            return [NSString stringWithFormat:@"main frame \"%@\"", name];
85        else
86            return @"main frame";
87    } else {
88        if (name)
89            return [NSString stringWithFormat:@"frame \"%@\"", name];
90        else
91            return @"frame (anonymous)";
92    }
93}
94@end
95
96@implementation FrameLoadDelegate
97
98- (id)init
99{
100    if ((self = [super init])) {
101        gcController = new GCController;
102        accessibilityController = new AccessibilityController;
103    }
104    return self;
105}
106
107- (void)dealloc
108{
109    delete gcController;
110    delete accessibilityController;
111    [super dealloc];
112}
113
114// Exec messages in the work queue until they're all done, or one of them starts a new load
115- (void)processWork:(id)dummy
116{
117    // if another load started, then wait for it to complete.
118    if (topLoadingFrame)
119        return;
120
121    // if we finish all the commands, we're ready to dump state
122    if (WorkQueue::shared()->processWork() && !gLayoutTestController->waitToDump())
123        dump();
124}
125
126- (void)webView:(WebView *)c locationChangeDone:(NSError *)error forDataSource:(WebDataSource *)dataSource
127{
128    if ([dataSource webFrame] == topLoadingFrame) {
129        topLoadingFrame = nil;
130        WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
131        if (!gLayoutTestController->waitToDump()) {
132            if (WorkQueue::shared()->count())
133                [self performSelector:@selector(processWork:) withObject:nil afterDelay:0];
134            else
135                dump();
136        }
137    }
138}
139
140- (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame
141{
142    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
143        NSString *string = [NSString stringWithFormat:@"%@ - didStartProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
144        printf ("%s\n", [string UTF8String]);
145    }
146
147    ASSERT([frame provisionalDataSource]);
148    // Make sure we only set this once per test.  If it gets cleared, and then set again, we might
149    // end up doing two dumps for one test.
150    if (!topLoadingFrame && !done)
151        topLoadingFrame = frame;
152
153    if (!done && gLayoutTestController->stopProvisionalFrameLoads()) {
154        NSString *string = [NSString stringWithFormat:@"%@ - stopping load in didStartProvisionalLoadForFrame callback", [frame _drt_descriptionSuitableForTestResult]];
155        printf ("%s\n", [string UTF8String]);
156        [frame stopLoading];
157    }
158}
159
160- (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame
161{
162    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
163        NSString *string = [NSString stringWithFormat:@"%@ - didCommitLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
164        printf ("%s\n", [string UTF8String]);
165    }
166
167    ASSERT(![frame provisionalDataSource]);
168    ASSERT([frame dataSource]);
169
170    gLayoutTestController->setWindowIsKey(true);
171    NSView *documentView = [[mainFrame frameView] documentView];
172    [[[mainFrame webView] window] makeFirstResponder:documentView];
173}
174
175- (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
176{
177    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
178        NSString *string = [NSString stringWithFormat:@"%@ - didFailProvisionalLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
179        printf ("%s\n", [string UTF8String]);
180    }
181
182    if ([error domain] == NSURLErrorDomain && ([error code] == NSURLErrorServerCertificateHasUnknownRoot || [error code] == NSURLErrorServerCertificateUntrusted)) {
183        NSURL *failedURL = [[error userInfo] objectForKey:@"NSErrorFailingURLKey"];
184        [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[failedURL _web_hostString]];
185        [frame loadRequest:[[[[frame provisionalDataSource] request] mutableCopy] autorelease]];
186        return;
187    }
188
189    ASSERT([frame provisionalDataSource]);
190    [self webView:sender locationChangeDone:error forDataSource:[frame provisionalDataSource]];
191}
192
193- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
194{
195    ASSERT([frame dataSource]);
196    ASSERT(frame == [[frame dataSource] webFrame]);
197
198    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
199        NSString *string = [NSString stringWithFormat:@"%@ - didFinishLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
200        printf ("%s\n", [string UTF8String]);
201    }
202
203    // FIXME: This call to displayIfNeeded can be removed when <rdar://problem/5092361> is fixed.
204    // After that is fixed, we will reenable painting after WebCore is done loading the document,
205    // and this call will no longer be needed.
206    if ([[sender mainFrame] isEqual:frame])
207        [sender displayIfNeeded];
208    [self webView:sender locationChangeDone:nil forDataSource:[frame dataSource]];
209    [gNavigationController webView:sender didFinishLoadForFrame:frame];
210}
211
212- (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
213{
214    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
215        NSString *string = [NSString stringWithFormat:@"%@ - didFailLoadWithError", [frame _drt_descriptionSuitableForTestResult]];
216        printf ("%s\n", [string UTF8String]);
217    }
218
219    ASSERT(![frame provisionalDataSource]);
220    ASSERT([frame dataSource]);
221
222    [self webView:sender locationChangeDone:error forDataSource:[frame dataSource]];
223}
224
225- (void)webView:(WebView *)webView windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject
226{
227    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
228        NSString *string = [NSString stringWithFormat:@"?? - windowScriptObjectAvailable"];
229        printf ("%s\n", [string UTF8String]);
230    }
231
232    ASSERT_NOT_REACHED();
233}
234
235- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)obj forFrame:(WebFrame *)frame
236{
237    ASSERT(obj == [frame windowObject]);
238    ASSERT([obj JSObject] == JSContextGetGlobalObject([frame globalContext]));
239
240    // Make New-Style LayoutTestController
241    JSContextRef context = [frame globalContext];
242    JSObjectRef globalObject = JSContextGetGlobalObject(context);
243    JSValueRef exception = 0;
244
245    ASSERT(gLayoutTestController);
246    gLayoutTestController->makeWindowObject(context, globalObject, &exception);
247    ASSERT(!exception);
248
249    gcController->makeWindowObject(context, globalObject, &exception);
250    ASSERT(!exception);
251
252    accessibilityController->makeWindowObject(context, globalObject, &exception);
253    ASSERT(!exception);
254
255    // Make Old-Style controllers
256
257    AppleScriptController *asc = [[AppleScriptController alloc] initWithWebView:sender];
258    [obj setValue:asc forKey:@"appleScriptController"];
259    [asc release];
260
261    EventSendingController *esc = [[EventSendingController alloc] init];
262    [obj setValue:esc forKey:@"eventSender"];
263    [esc release];
264
265    [obj setValue:gNavigationController forKey:@"navigationController"];
266
267    ObjCController *occ = [[ObjCController alloc] init];
268    [obj setValue:occ forKey:@"objCController"];
269    [occ release];
270
271    ObjCPlugin *plugin = [[ObjCPlugin alloc] init];
272    [obj setValue:plugin forKey:@"objCPlugin"];
273    [plugin release];
274
275    ObjCPluginFunction *pluginFunction = [[ObjCPluginFunction alloc] init];
276    [obj setValue:pluginFunction forKey:@"objCPluginFunction"];
277    [pluginFunction release];
278
279    [obj setValue:[PlainTextController sharedPlainTextController] forKey:@"plainText"];
280
281    TextInputController *tic = [[TextInputController alloc] initWithWebView:sender];
282    [obj setValue:tic forKey:@"textInputController"];
283    [tic release];
284}
285
286- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
287{
288    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
289        NSString *string = [NSString stringWithFormat:@"%@ - didReceiveTitle: %@", [frame _drt_descriptionSuitableForTestResult], title];
290        printf ("%s\n", [string UTF8String]);
291    }
292
293    if (gLayoutTestController->dumpTitleChanges())
294        printf("TITLE CHANGED: %s\n", [title UTF8String]);
295}
296
297- (void)webView:(WebView *)sender didReceiveServerRedirectForProvisionalLoadForFrame:(WebFrame *)frame
298{
299    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
300        NSString *string = [NSString stringWithFormat:@"%@ - didReceiveServerRedirectForProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
301        printf ("%s\n", [string UTF8String]);
302    }
303}
304
305- (void)webView:(WebView *)sender didChangeLocationWithinPageForFrame:(WebFrame *)frame
306{
307    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
308        NSString *string = [NSString stringWithFormat:@"%@ - didChangeLocationWithinPageForFrame", [frame _drt_descriptionSuitableForTestResult]];
309        printf ("%s\n", [string UTF8String]);
310    }
311}
312
313- (void)webView:(WebView *)sender willPerformClientRedirectToURL:(NSURL *)URL delay:(NSTimeInterval)seconds fireDate:(NSDate *)date forFrame:(WebFrame *)frame
314{
315    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
316        NSString *string = [NSString stringWithFormat:@"%@ - willPerformClientRedirectToURL: %@ ", [frame _drt_descriptionSuitableForTestResult], [URL _drt_descriptionSuitableForTestResult]];
317        printf ("%s\n", [string UTF8String]);
318    }
319}
320
321- (void)webView:(WebView *)sender didCancelClientRedirectForFrame:(WebFrame *)frame
322{
323    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
324        NSString *string = [NSString stringWithFormat:@"%@ - didCancelClientRedirectForFrame", [frame _drt_descriptionSuitableForTestResult]];
325        printf ("%s\n", [string UTF8String]);
326    }
327}
328
329- (void)webView:(WebView *)sender didFinishDocumentLoadForFrame:(WebFrame *)frame
330{
331    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
332        NSString *string = [NSString stringWithFormat:@"%@ - didFinishDocumentLoadForFrame", [frame _drt_descriptionSuitableForTestResult]];
333        printf ("%s\n", [string UTF8String]);
334    } else if (!done) {
335        unsigned pendingFrameUnloadEvents = [frame _pendingFrameUnloadEventCount];
336        if (pendingFrameUnloadEvents) {
337            NSString *string = [NSString stringWithFormat:@"%@ - has %u onunload handler(s)", [frame _drt_descriptionSuitableForTestResult], pendingFrameUnloadEvents];
338            printf ("%s\n", [string UTF8String]);
339        }
340    }
341}
342
343- (void)webView:(WebView *)sender didHandleOnloadEventsForFrame:(WebFrame *)frame
344{
345    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
346        NSString *string = [NSString stringWithFormat:@"%@ - didHandleOnloadEventsForFrame", [frame _drt_descriptionSuitableForTestResult]];
347        printf ("%s\n", [string UTF8String]);
348    }
349}
350
351@end
352