9e53b3f1623bcdb4a1af39a38fc10b1a63385756
[WebKit-https.git] / WebKitTools / DumpRenderTree / LayoutTestControllerMac.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 "LayoutTestController.h"
30
31 #import "DumpRenderTree.h"
32 #import "EditingDelegate.h"
33 #import "WorkQueue.h"
34 #import "WorkQueueItem.h"
35 #import <JavaScriptCore/JSRetainPtr.h>
36 #import <JavaScriptCore/JSStringRef.h>
37 #import <JavaScriptCore/JSStringRefCF.h>
38 #import <JavaScriptCore/RetainPtr.h>
39 #import <WebKit/WebBackForwardList.h>
40 #import <WebKit/WebFrame.h>
41 #import <WebKit/WebHTMLViewPrivate.h>
42 #import <WebKit/WebHistory.h>
43 #import <WebKit/WebNSURLExtras.h>
44 #import <WebKit/WebPreferences.h>
45 #import <WebKit/WebView.h>
46 #import <WebKit/WebViewPrivate.h>
47
48 #import <Foundation/Foundation.h>
49
50 void LayoutTestController::dumpAsText()
51 {
52     ::dumpAsText = true;
53 }
54
55 void LayoutTestController::dumpBackForwardList()
56 {
57     ::dumpBackForwardList = true;
58 }
59
60 void LayoutTestController::dumpChildFramesAsText()
61 {
62     ::dumpChildFramesAsText = true;
63 }
64
65 void LayoutTestController::dumpChildFrameScrollPositions()
66 {
67     ::dumpChildFrameScrollPositions = true;
68 }
69
70 void LayoutTestController::dumpDOMAsWebArchive()
71 {
72     ::dumpDOMAsWebArchive = true;
73 }
74
75 void LayoutTestController::dumpEditingCallbacks()
76 {
77     ::shouldDumpEditingCallbacks = true;
78 }
79
80 void LayoutTestController::dumpFrameLoadCallbacks()
81 {
82     ::shouldDumpFrameLoadCallbacks = true;
83 }
84
85 void LayoutTestController::dumpResourceLoadCallbacks()
86 {
87     ::shouldDumpResourceLoadCallbacks = true;
88 }
89
90 void LayoutTestController::dumpSelectionRect()
91 {
92     ::dumpSelectionRect = true;
93 }
94
95 void LayoutTestController::dumpSourceAsWebArchive()
96 {
97     ::dumpSourceAsWebArchive = true;
98 }
99
100 void LayoutTestController::dumpTitleChanges()
101 {
102     ::dumpTitleChanges = true;
103 }
104
105 void LayoutTestController::repaintSweepHorizontally()
106 {
107     ::repaintSweepHorizontally = true;
108 }
109
110 void LayoutTestController::setCallCloseOnWebViews()
111 {
112     ::closeWebViews = true;
113 }
114
115 void LayoutTestController::setCanOpenWindows()
116 {
117     ::canOpenWindows = true;
118 }
119
120 void LayoutTestController::setCloseRemainingWindowsWhenComplete()
121 {
122     ::closeRemainingWindowsWhenComplete = true;
123 }
124
125 void LayoutTestController::testRepaint()
126 {
127     ::testRepaint = true;
128 }
129
130 void LayoutTestController::addFileToPasteboardOnDrag()
131 {
132     ::addFileToPasteboardOnDrag = true;
133 }
134
135 void LayoutTestController::addDisallowedURL(JSStringRef url)
136 {
137     RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url));
138
139     if (!disallowedURLs)
140         disallowedURLs = [[NSMutableSet alloc] init];
141
142     // Canonicalize the URL
143     NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:(NSString *)urlCF.get()]];
144     request = [NSURLProtocol canonicalRequestForRequest:request];
145
146     [disallowedURLs addObject:[request URL]];
147 }
148
149 void LayoutTestController::clearBackForwardList()
150 {
151     WebBackForwardList *backForwardList = [[mainFrame webView] backForwardList];
152     WebHistoryItem *item = [[backForwardList currentItem] retain];
153
154     // We clear the history by setting the back/forward list's capacity to 0
155     // then restoring it back and adding back the current item.
156     int capacity = [backForwardList capacity];
157     [backForwardList setCapacity:0];
158     [backForwardList setCapacity:capacity];
159     [backForwardList addItem:item];
160     [backForwardList goToItem:item];
161     [item release];
162 }
163
164 JSStringRef LayoutTestController::decodeHostName(JSStringRef name)
165 {
166     RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
167     NSString *nameNS = (NSString *)nameCF.get();
168     return JSStringCreateWithCFString((CFStringRef)[nameNS _web_decodeHostName]);
169 }
170
171 JSStringRef LayoutTestController::encodeHostName(JSStringRef name)
172 {
173     RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
174     NSString *nameNS = (NSString *)nameCF.get();
175     return JSStringCreateWithCFString((CFStringRef)[nameNS _web_encodeHostName]);
176 }
177
178 void LayoutTestController::display()
179 {
180     displayWebView();
181 }
182
183 void LayoutTestController::keepWebHistory()
184 {
185     if (![WebHistory optionalSharedHistory]) {
186         WebHistory *history = [[WebHistory alloc] init];
187         [WebHistory setOptionalSharedHistory:history];
188         [history release];
189     }
190 }
191
192 void LayoutTestController::notifyDone()
193 {
194     if (waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
195         dump();
196     waitToDump = false;
197 }
198
199 void LayoutTestController::queueBackNavigation(int howFarBack)
200 {
201     WorkQueue::shared()->queue(new BackItem(howFarBack));
202 }
203
204 void LayoutTestController::queueForwardNavigation(int howFarForward)
205 {
206     WorkQueue::shared()->queue(new ForwardItem(howFarForward));
207 }
208
209 void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
210 {
211     RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url));
212     NSString *urlNS = (NSString *)urlCF.get();
213
214     NSURL *nsurl = [NSURL URLWithString:urlNS relativeToURL:[[[mainFrame dataSource] response] URL]];
215     NSString* nsurlString = [nsurl absoluteString];
216
217     WorkQueue::shared()->queue(new LoadItem(JSStringCreateWithUTF8CString([nsurlString UTF8String]), target));
218 }
219
220 void LayoutTestController::queueReload()
221 {
222     WorkQueue::shared()->queue(new ReloadItem);
223 }
224
225 void LayoutTestController::queueScript(JSStringRef script)
226 {
227     WorkQueue::shared()->queue(new ScriptItem(script));
228 }
229
230 void LayoutTestController::setAcceptsEditing(bool newAcceptsEditing)
231 {
232     [(EditingDelegate *)[[mainFrame webView] editingDelegate] setAcceptsEditing:newAcceptsEditing];
233 }
234
235 void LayoutTestController::setCustomPolicyDelegate(bool setDelegate)
236 {
237     if (setDelegate)
238         [[mainFrame webView] setPolicyDelegate:policyDelegate];
239     else
240         [[mainFrame webView] setPolicyDelegate:nil];
241 }
242
243 void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
244 {
245     NSView *documentView = [[mainFrame frameView] documentView];
246     
247     NSResponder *firstResponder = flag ? documentView : nil;
248     [[[mainFrame webView] window] makeFirstResponder:firstResponder];
249         
250     if ([documentView isKindOfClass:[WebHTMLView class]])
251         [(WebHTMLView *)documentView _updateActiveState];
252 }
253
254 void LayoutTestController::setTabKeyCyclesThroughElements(bool cycles)
255 {
256     [[mainFrame webView] setTabKeyCyclesThroughElements:cycles];
257 }
258
259 void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
260 {
261     [[mainFrame webView] _setDashboardBehavior:WebDashboardBehaviorUseBackwardCompatibilityMode to:flag];
262 }
263
264 void LayoutTestController::setUserStyleSheetEnabled(bool flag)
265 {
266     [[WebPreferences standardPreferences] setUserStyleSheetEnabled:flag];
267 }
268
269 void LayoutTestController::setUserStyleSheetLocation(JSStringRef path)
270 {
271     RetainPtr<CFStringRef> pathCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, path));
272     NSURL *url = [NSURL URLWithString:(NSString *)pathCF.get()];
273     [[WebPreferences standardPreferences] setUserStyleSheetLocation:url];
274 }
275
276 void LayoutTestController::setWindowIsKey(bool flag)
277 {
278     windowIsKey = flag;
279     NSView *documentView = [[mainFrame frameView] documentView];
280     if ([documentView isKindOfClass:[WebHTMLView class]])
281         [(WebHTMLView *)documentView _updateActiveState];
282 }
283
284 @interface WaitToDumpWatchdog : NSObject
285 + (void)waitUntilDoneWatchdogFired;
286 @end
287
288 @implementation WaitToDumpWatchdog
289 + (void)waitUntilDoneWatchdogFired
290 {
291     const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
292     fprintf(stderr, message);
293     fprintf(stdout, message);
294     dump();
295 }
296 @end
297
298 void LayoutTestController::waitUntilDone()
299 {
300     waitToDump = true;
301     if (!waitToDumpWatchdog)
302         waitToDumpWatchdog = [[NSTimer scheduledTimerWithTimeInterval:waitToDumpWatchdogInterval target:[WaitToDumpWatchdog class] selector:@selector(waitUntilDoneWatchdogFired) userInfo:nil repeats:NO] retain];
303 }
304
305 int LayoutTestController::windowCount()
306 {
307     return CFArrayGetCount(allWindowsRef);
308 }