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