Reviewed by Eric.

        - Added back/forward navigation support to DumpRenderTree. Hopefully we
        can start writing automated loader tests now. I have one in the works.

        * DumpRenderTree/DumpRenderTree.m:
        (main): Construct global navigationController on entry, destroy on exit.
        Set frame to nil on exit too, to match all the other global objects. 
        (Probably academic, since the process is exiting, anyway.)
        (-[WaitUntilDoneDelegate webView:didFinishLoadForFrame:]): Notify the
        navigationController, in case it wants to kick off a load.
        (-[WaitUntilDoneDelegate webView:windowScriptObjectAvailable:]): Expose
        the navigationController to scripting.

        New class, should be straightforward:

        * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
        * DumpRenderTree/NavigationController.h: Added.
        * DumpRenderTree/NavigationController.m: Added.

        (+[NavigationController isSelectorExcludedFromWebScript:]):
        (+[NavigationController webScriptNameForSelector:]):
        (-[NavigationController setPendingScript:]):
        (-[NavigationController setPendingRequest:]):
        (-[NavigationController evaluateWebScript:afterBackForwardNavigation:]):
        (-[NavigationController webView:didFinishLoadForFrame:]):
        (-[NavigationController dealloc]):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@11943 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index 770cf0a..9d3ccac 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,33 @@
+2006-01-08  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Eric.
+
+        - Added back/forward navigation support to DumpRenderTree. Hopefully we
+        can start writing automated loader tests now. I have one in the works.
+
+        * DumpRenderTree/DumpRenderTree.m:
+        (main): Construct global navigationController on entry, destroy on exit.
+        Set frame to nil on exit too, to match all the other global objects. 
+        (Probably academic, since the process is exiting, anyway.)
+        (-[WaitUntilDoneDelegate webView:didFinishLoadForFrame:]): Notify the
+        navigationController, in case it wants to kick off a load.
+        (-[WaitUntilDoneDelegate webView:windowScriptObjectAvailable:]): Expose
+        the navigationController to scripting.
+
+        New class, should be straightforward:
+
+        * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
+        * DumpRenderTree/NavigationController.h: Added.
+        * DumpRenderTree/NavigationController.m: Added.
+
+        (+[NavigationController isSelectorExcludedFromWebScript:]):
+        (+[NavigationController webScriptNameForSelector:]):
+        (-[NavigationController setPendingScript:]):
+        (-[NavigationController setPendingRequest:]):
+        (-[NavigationController evaluateWebScript:afterBackForwardNavigation:]):
+        (-[NavigationController webView:didFinishLoadForFrame:]):
+        (-[NavigationController dealloc]):
+
 2006-01-08  Timothy Hatcher  <timothy@apple.com>
 
         Removed this script, no longer needs with the Subversion switch.
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.m b/WebKitTools/DumpRenderTree/DumpRenderTree.m
index 1338c73..5cd2ac5 100644
--- a/WebKitTools/DumpRenderTree/DumpRenderTree.m
+++ b/WebKitTools/DumpRenderTree/DumpRenderTree.m
@@ -45,6 +45,7 @@
 #import <getopt.h>
 
 #import "TextInputController.h"
+#import "NavigationController.h"
 
 @interface DumpRenderTreePasteboard : NSPasteboard
 @end
@@ -73,6 +74,7 @@
 
 static volatile BOOL done;
 static WebFrame *frame;
+static NavigationController *navigationController;
 static BOOL readyToDump;
 static BOOL waitToDump;
 static BOOL dumpAsText;
@@ -183,6 +185,7 @@
         setDefaultColorProfileToRGB();
     
     localPasteboard = [NSPasteboard pasteboardWithUniqueName];
+    navigationController = [[NavigationController alloc] init];
 
     WebView *webView = [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)];
     WaitUntilDoneDelegate *delegate = [[WaitUntilDoneDelegate alloc] init];
@@ -196,7 +199,7 @@
     // dynamic scrollbars properly. Without it, every frame will always have scrollbars.
     NSBitmapImageRep *imageRep = [webView bitmapImageRepForCachingDisplayInRect:[webView bounds]];
     [webView cacheDisplayInRect:[webView bounds] toBitmapImageRep:imageRep];
-
+    
     if (argc == optind+1 && strcmp(argv[optind], "-") == 0) {
         char filenameBuffer[2048];
         printSeparators = YES;
@@ -221,6 +224,7 @@
     [webView setFrameLoadDelegate:nil];
     [webView setEditingDelegate:nil];
     [webView setUIDelegate:nil];
+    frame = nil;
 
     [webView release];
     [delegate release];
@@ -229,6 +233,9 @@
     [localPasteboard releaseGlobally];
     localPasteboard = nil;
     
+    [navigationController release];
+    navigationController = nil;
+    
     if (dumpPixels)
         restoreColorSpace(0);
     
@@ -319,6 +326,7 @@
 - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
 {
     [self webView:sender locationChangeDone:nil forDataSource:[frame dataSource]];
+    [navigationController webView:sender didFinishLoadForFrame:frame];
 }
 
 - (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
@@ -337,6 +345,7 @@
     TextInputController *tic = [[TextInputController alloc] initWithWebView:sender];
     [obj setValue:tic forKey:@"textInputController"];
     [tic release];
+    [obj setValue:navigationController forKey:@"navigationController"];
 }
 
 - (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
index a327fd6..183567d 100644
--- a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
+++ b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
@@ -45,6 +45,8 @@
 		141BF44B096A45C800E0753C /* PluginObject.c in Sources */ = {isa = PBXBuildFile; fileRef = 141BF446096A45C800E0753C /* PluginObject.c */; };
 		141BF44C096A45C800E0753C /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 141BF448096A45C800E0753C /* Info.plist */; };
 		141BF453096A45EB00E0753C /* PluginObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 141BF447096A45C800E0753C /* PluginObject.h */; };
+		14A6FB8A0971CAE5008B014F /* NavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A6FB880971CAE5008B014F /* NavigationController.h */; };
+		14A6FB8B0971CAE5008B014F /* NavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 14A6FB890971CAE5008B014F /* NavigationController.m */; };
 		9340994C08540CAE007F3BC8 /* DumpRenderTreePrefix.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A70AAB03705E1F00C91783 /* DumpRenderTreePrefix.h */; };
 		9340994E08540CAE007F3BC8 /* DumpRenderTree.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* DumpRenderTree.m */; settings = {ATTRIBUTES = (); }; };
 		9340995108540CAE007F3BC8 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9335435F03D75502008635CE /* WebKit.framework */; };
@@ -108,6 +110,8 @@
 		141BF446096A45C800E0753C /* PluginObject.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = PluginObject.c; path = ../TestNetscapePlugIn.subproj/PluginObject.c; sourceTree = "<group>"; };
 		141BF447096A45C800E0753C /* PluginObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PluginObject.h; path = ../TestNetscapePlugIn.subproj/PluginObject.h; sourceTree = "<group>"; };
 		141BF448096A45C800E0753C /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = Info.plist; path = ../TestNetscapePlugIn.subproj/Info.plist; sourceTree = "<group>"; };
+		14A6FB880971CAE5008B014F /* NavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigationController.h; sourceTree = "<group>"; };
+		14A6FB890971CAE5008B014F /* NavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NavigationController.m; sourceTree = "<group>"; };
 		32A70AAB03705E1F00C91783 /* DumpRenderTreePrefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DumpRenderTreePrefix.h; sourceTree = "<group>"; };
 		9335435F03D75502008635CE /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WebKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		9340995408540CAF007F3BC8 /* DumpRenderTree */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = DumpRenderTree; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -176,6 +180,8 @@
 				A84F608908B136DA00E9745F /* Cocoa.framework */,
 				AE8257EF08D22389000507AB /* Carbon.framework */,
 				9340995508540CAF007F3BC8 /* Products */,
+				14A6FB880971CAE5008B014F /* NavigationController.h */,
+				14A6FB890971CAE5008B014F /* NavigationController.m */,
 			);
 			name = DumpRenderTree;
 			sourceTree = "<group>";
@@ -218,6 +224,7 @@
 			files = (
 				9340994C08540CAE007F3BC8 /* DumpRenderTreePrefix.h in Headers */,
 				93442CF608F8BA4900BFE8CA /* TextInputController.h in Headers */,
+				14A6FB8A0971CAE5008B014F /* NavigationController.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -406,6 +413,7 @@
 			files = (
 				9340994E08540CAE007F3BC8 /* DumpRenderTree.m in Sources */,
 				93442CF708F8BA4900BFE8CA /* TextInputController.m in Sources */,
+				14A6FB8B0971CAE5008B014F /* NavigationController.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/WebKitTools/DumpRenderTree/NavigationController.h b/WebKitTools/DumpRenderTree/NavigationController.h
new file mode 100644
index 0000000..8ee3432
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/NavigationController.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import <WebKit/WebView.h>
+
+@interface NavigationController : NSObject
+{
+    enum { None, Load, GoBack, ExecuteScript } pendingAction;
+    NSString *pendingScript;
+    NSURLRequest *pendingRequest;
+}
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame;
+@end
diff --git a/WebKitTools/DumpRenderTree/NavigationController.m b/WebKitTools/DumpRenderTree/NavigationController.m
new file mode 100644
index 0000000..44aed8a
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/NavigationController.m
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <WebKit/WebFrame.h>
+#import <WebKit/WebScriptObject.h>
+#import "NavigationController.h"
+
+@implementation NavigationController
++ (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
+{
+    if (selector == @selector(evaluateWebScript:afterBackForwardNavigation:))
+        return NO;
+    return YES;
+}
+
++ (NSString *)webScriptNameForSelector:(SEL)selector
+{
+    if (selector == @selector(evaluateWebScript:afterBackForwardNavigation:))
+        return @"evalAfterBackForwardNavigation";
+    return nil;
+}
+
+- (void)setPendingScript:(NSString *)script
+{
+    if (script != pendingScript) {
+        [pendingScript release];
+        pendingScript = [script copy];
+    }
+}
+
+- (void)setPendingRequest:(NSURLRequest *)request
+{
+    if (request != pendingRequest) {
+        [pendingRequest release];
+        pendingRequest = [request copy];
+    }
+}
+
+- (void)evaluateWebScript:(NSString *)script afterBackForwardNavigation:(NSString *)navigation
+{
+    // Allow both arguments to be optional
+    if (![script isKindOfClass:[NSString class]])
+        script = @"";
+    if (![navigation isKindOfClass:[NSString class]])
+        navigation = @"about:blank";
+    
+    [self setPendingScript:script];
+    [self setPendingRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:navigation]]];
+    pendingAction = Load;
+}
+
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
+{
+    if (frame == [[frame webView] mainFrame]) {
+        switch (pendingAction) {
+            case Load:
+                pendingAction = GoBack;
+                [frame loadRequest:pendingRequest];
+                [self setPendingRequest:nil];
+                break;
+            case GoBack:
+                pendingAction = ExecuteScript;
+                [[frame webView] goBack];
+                break;
+            case ExecuteScript:
+                pendingAction = None;
+                [[[frame webView] windowScriptObject] evaluateWebScript:pendingScript];
+                [self setPendingScript:nil];
+                break;
+            case None:
+            default:
+                break;
+        }
+    }
+}
+
+- (void)dealloc
+{
+    [self setPendingScript:nil];
+    [self setPendingRequest:nil];
+    [super dealloc];
+}
+@end
+