JavaScriptCore:
[WebKit-https.git] / WebKitTools / DumpRenderTree / DumpRenderTree.m
1 /*
2  * Copyright (C) 2005 Apple Computer, 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 <Foundation/NSURLRequest.h>
30 #import <Foundation/NSError.h>
31
32 #import <WebKit/DOMExtensions.h>
33 #import <WebKit/WebCoreStatistics.h>
34 #import <WebKit/WebDataSource.h>
35 #import <WebKit/WebFrame.h>
36 #import <WebKit/WebFrameLoadDelegate.h>
37 #import <WebKit/WebFrameView.h>
38 #import <WebKit/WebPreferences.h>
39 #import <WebKit/WebView.h>
40
41 @interface WaitUntilDoneDelegate : NSObject
42 @end
43
44 @interface LayoutTestController : NSObject
45 @end
46
47 static void dumpRenderTree(const char *filename);
48
49 static volatile BOOL done;
50 static WebFrame *frame;
51 static BOOL readyToDump;
52 static BOOL waitToDump;
53 static BOOL dumpAsText;
54 static BOOL dumpTitleChanges;
55
56 int main(int argc, const char *argv[])
57 {
58     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
59
60     WebPreferences *preferences = [WebPreferences standardPreferences];
61     
62     NSString *standardFontFamily = [preferences standardFontFamily];
63     NSString *fixedFontFamily = [preferences fixedFontFamily];
64     NSString *serifFontFamily = [preferences serifFontFamily];
65     NSString *sansSerifFontFamily = [preferences sansSerifFontFamily];
66     NSString *cursiveFontFamily = [preferences cursiveFontFamily];
67     NSString *fantasyFontFamily = [preferences fantasyFontFamily];
68     int defaultFontSize = [preferences defaultFontSize];
69     int defaultFixedFontSize = [preferences defaultFixedFontSize];
70     int minimumFontSize = [preferences minimumFontSize];
71     
72     [preferences setStandardFontFamily:@"Times"];
73     [preferences setFixedFontFamily:@"Courier"];
74     [preferences setSerifFontFamily:@"Times"];
75     [preferences setSansSerifFontFamily:@"Helvetica"];
76     [preferences setCursiveFontFamily:@"Apple Chancery"];
77     [preferences setFantasyFontFamily:@"Papyrus"];
78     [preferences setDefaultFontSize:16];
79     [preferences setDefaultFixedFontSize:13];
80     [preferences setMinimumFontSize:9];
81
82     WebView *webView = [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)];
83     WaitUntilDoneDelegate *delegate = [[WaitUntilDoneDelegate alloc] init];
84     [webView setFrameLoadDelegate:delegate];
85     [webView setUIDelegate:delegate];
86     frame = [webView mainFrame];
87     
88     if (argc == 2 && strcmp(argv[1], "-") == 0) {
89         char filenameBuffer[2048];
90         while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
91             char *newLineCharacter = strchr(filenameBuffer, '\n');
92             if (newLineCharacter) {
93                 *newLineCharacter = '\0';
94             }
95             dumpRenderTree(filenameBuffer);
96             puts("#EOF");
97             fflush(stdout);
98         }
99     } else {
100         int i;
101         for (i = 1; i != argc; ++i) {
102             dumpRenderTree(argv[i]);
103         }
104     }
105     
106     [preferences setStandardFontFamily:standardFontFamily];
107     [preferences setFixedFontFamily:fixedFontFamily];
108     [preferences setSerifFontFamily:serifFontFamily];
109     [preferences setSansSerifFontFamily:sansSerifFontFamily];
110     [preferences setCursiveFontFamily:cursiveFontFamily];
111     [preferences setFantasyFontFamily:fantasyFontFamily];
112     [preferences setDefaultFontSize:defaultFontSize];
113     [preferences setDefaultFixedFontSize:defaultFixedFontSize];
114     [preferences setMinimumFontSize:minimumFontSize];
115
116     [pool release];
117     return 0;
118 }
119
120 static void dump(void)
121 {
122     NSString *result = nil;
123     if (dumpAsText) {
124         DOMDocument *document = [frame DOMDocument];
125         if ([document isKindOfClass:[DOMHTMLDocument class]]) {
126             result = [[[(DOMHTMLDocument *)document body] innerText] stringByAppendingString:@"\n"];
127         }
128     } else {
129         result = [frame renderTreeAsExternalRepresentation];
130     }
131     if (!result) {
132         puts("error");
133     } else {
134         fputs([result UTF8String], stdout);
135     }
136     done = YES;
137 }
138
139 @implementation WaitUntilDoneDelegate
140
141 - (void)webView:(WebView *)c locationChangeDone:(NSError *)error forDataSource:(WebDataSource *)dataSource
142 {
143     if ([dataSource webFrame] == frame) {
144         if (waitToDump)
145             readyToDump = YES;
146         else
147             dump();
148     }
149 }
150
151 - (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
152 {
153     [self webView:sender locationChangeDone:error forDataSource:[frame provisionalDataSource]];
154 }
155
156 - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
157 {
158     [self webView:sender locationChangeDone:nil forDataSource:[frame dataSource]];
159 }
160
161 - (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
162 {
163     [self webView:sender locationChangeDone:error forDataSource:[frame dataSource]];
164 }
165
166 - (void)webView:(WebView *)sender windowScriptObjectAvailable:(WebScriptObject *)obj 
167
168     LayoutTestController *ltc = [[LayoutTestController alloc] init];
169     [(id)obj setValue:ltc forKey:@"layoutTestController"];
170     [ltc release];
171
172 }
173
174 - (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message
175 {
176     printf("ALERT: %s\n", [message UTF8String]);
177 }
178
179 - (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
180 {
181     if (dumpTitleChanges)
182         printf("TITLE CHANGED: %s\n", [title UTF8String]);
183 }
184
185 @end
186
187 @implementation LayoutTestController
188
189 + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
190 {
191     if (aSelector == @selector(waitUntilDone)
192             || aSelector == @selector(notifyDone)
193             || aSelector == @selector(dumpAsText)
194             || aSelector == @selector(dumpTitleChanges))
195         return NO;
196     return YES;
197 }
198
199 - (void)waitUntilDone 
200 {
201     waitToDump = YES;
202 }
203
204 - (void)notifyDone
205 {
206     if (waitToDump && readyToDump)
207         dump();
208     waitToDump = NO;
209 }
210
211 - (void)dumpAsText
212 {
213     dumpAsText = YES;
214 }
215
216 - (void)dumpTitleChanges
217 {
218     dumpTitleChanges = YES;
219 }
220
221 @end
222
223 static void dumpRenderTree(const char *filename)
224 {
225     CFStringRef filenameString = CFStringCreateWithCString(NULL, filename, kCFStringEncodingUTF8);
226     if (filenameString == NULL) {
227         fprintf(stderr, "can't parse filename as UTF-8\n");
228         return;
229     }
230     CFURLRef URL = CFURLCreateWithFileSystemPath(NULL, filenameString, kCFURLPOSIXPathStyle, FALSE);
231     if (URL == NULL) {
232         fprintf(stderr, "can't turn %s into a CFURL\n", filename);
233         return;
234     }
235
236     done = NO;
237     readyToDump = NO;
238     waitToDump = NO;
239     dumpAsText = NO;
240     dumpTitleChanges = NO;
241
242     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
243     [frame loadRequest:[NSURLRequest requestWithURL:(NSURL *)URL]];
244     [pool release];
245     while (!done) {
246         pool = [[NSAutoreleasePool alloc] init];
247         [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
248         [pool release];
249     }
250 }