WebKitTools:
[WebKit-https.git] / WebKitTools / DumpRenderTree / mac / 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 "DumpRenderTree.h"
30 #import "LayoutTestController.h"
31
32 #import "EditingDelegate.h"
33 #import "WorkQueue.h"
34 #import "WorkQueueItem.h"
35 #import <Foundation/Foundation.h>
36 #import <JavaScriptCore/JSRetainPtr.h>
37 #import <JavaScriptCore/JSStringRef.h>
38 #import <JavaScriptCore/JSStringRefCF.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/WebPreferencesPrivate.h>
46 #import <WebKit/WebView.h>
47 #import <WebKit/WebViewPrivate.h>
48 #import <wtf/RetainPtr.h>
49
50 LayoutTestController::~LayoutTestController()
51 {
52 }
53
54 void LayoutTestController::addDisallowedURL(JSStringRef url)
55 {
56     RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url));
57
58     if (!disallowedURLs)
59         disallowedURLs = CFSetCreateMutable(kCFAllocatorDefault, 0, NULL);
60
61     // Canonicalize the URL
62     NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:(NSString *)urlCF.get()]];
63     request = [NSURLProtocol canonicalRequestForRequest:request];
64
65     CFSetAddValue(disallowedURLs, [request URL]);
66 }
67
68 void LayoutTestController::clearBackForwardList()
69 {
70     WebBackForwardList *backForwardList = [[mainFrame webView] backForwardList];
71     WebHistoryItem *item = [[backForwardList currentItem] retain];
72
73     // We clear the history by setting the back/forward list's capacity to 0
74     // then restoring it back and adding back the current item.
75     int capacity = [backForwardList capacity];
76     [backForwardList setCapacity:0];
77     [backForwardList setCapacity:capacity];
78     [backForwardList addItem:item];
79     [backForwardList goToItem:item];
80     [item release];
81 }
82
83 JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name)
84 {
85     RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
86     NSString *nameNS = (NSString *)nameCF.get();
87     return JSStringCreateWithCFString((CFStringRef)[nameNS _web_decodeHostName]);
88 }
89
90 JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name)
91 {
92     RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
93     NSString *nameNS = (NSString *)nameCF.get();
94     return JSStringCreateWithCFString((CFStringRef)[nameNS _web_encodeHostName]);
95 }
96
97 void LayoutTestController::display()
98 {
99     displayWebView();
100 }
101
102 void LayoutTestController::keepWebHistory()
103 {
104     if (![WebHistory optionalSharedHistory]) {
105         WebHistory *history = [[WebHistory alloc] init];
106         [WebHistory setOptionalSharedHistory:history];
107         [history release];
108     }
109 }
110
111 void LayoutTestController::notifyDone()
112 {
113     if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
114         dump();
115     m_waitToDump = false;
116 }
117
118 JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url)
119 {
120     return url; // Do nothing on mac.
121 }
122
123 void LayoutTestController::queueBackNavigation(int howFarBack)
124 {
125     WorkQueue::shared()->queue(new BackItem(howFarBack));
126 }
127
128 void LayoutTestController::queueForwardNavigation(int howFarForward)
129 {
130     WorkQueue::shared()->queue(new ForwardItem(howFarForward));
131 }
132
133 void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
134 {
135     RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url));
136     NSString *urlNS = (NSString *)urlCF.get();
137
138     NSURL *nsurl = [NSURL URLWithString:urlNS relativeToURL:[[[mainFrame dataSource] response] URL]];
139     NSString* nsurlString = [nsurl absoluteString];
140
141     JSRetainPtr<JSStringRef> absoluteURL(Adopt, JSStringCreateWithUTF8CString([nsurlString UTF8String]));
142     WorkQueue::shared()->queue(new LoadItem(absoluteURL.get(), target));
143 }
144
145 void LayoutTestController::queueReload()
146 {
147     WorkQueue::shared()->queue(new ReloadItem);
148 }
149
150 void LayoutTestController::queueScript(JSStringRef script)
151 {
152     WorkQueue::shared()->queue(new ScriptItem(script));
153 }
154
155 void LayoutTestController::setAcceptsEditing(bool newAcceptsEditing)
156 {
157     [(EditingDelegate *)[[mainFrame webView] editingDelegate] setAcceptsEditing:newAcceptsEditing];
158 }
159
160 void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag)
161 {
162     [[[mainFrame webView] preferences] setAuthorAndUserStylesEnabled:flag];
163 }
164
165 void LayoutTestController::setCustomPolicyDelegate(bool setDelegate)
166 {
167     if (setDelegate)
168         [[mainFrame webView] setPolicyDelegate:policyDelegate];
169     else
170         [[mainFrame webView] setPolicyDelegate:nil];
171 }
172
173 void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
174 {
175     NSView *documentView = [[mainFrame frameView] documentView];
176     
177     NSResponder *firstResponder = flag ? documentView : nil;
178     [[[mainFrame webView] window] makeFirstResponder:firstResponder];
179         
180     if ([documentView isKindOfClass:[WebHTMLView class]])
181         [(WebHTMLView *)documentView _updateActiveState];
182 }
183
184 void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
185 {
186     [[[mainFrame webView] preferences] setPrivateBrowsingEnabled:privateBrowsingEnabled];
187 }
188
189 void LayoutTestController::setTabKeyCyclesThroughElements(bool cycles)
190 {
191     [[mainFrame webView] setTabKeyCyclesThroughElements:cycles];
192 }
193
194 void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
195 {
196     [[mainFrame webView] _setDashboardBehavior:WebDashboardBehaviorUseBackwardCompatibilityMode to:flag];
197 }
198
199 void LayoutTestController::setUserStyleSheetEnabled(bool flag)
200 {
201     [[WebPreferences standardPreferences] setUserStyleSheetEnabled:flag];
202 }
203
204 void LayoutTestController::setUserStyleSheetLocation(JSStringRef path)
205 {
206     RetainPtr<CFStringRef> pathCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, path));
207     NSURL *url = [NSURL URLWithString:(NSString *)pathCF.get()];
208     [[WebPreferences standardPreferences] setUserStyleSheetLocation:url];
209 }
210
211 void LayoutTestController::setWindowIsKey(bool windowIsKey)
212 {
213     m_windowIsKey = windowIsKey;
214     NSView *documentView = [[mainFrame frameView] documentView];
215     if ([documentView isKindOfClass:[WebHTMLView class]])
216         [(WebHTMLView *)documentView _updateActiveState];
217 }
218
219 static const CFTimeInterval waitToDumpWatchdogInterval = 10.0;
220
221 static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)
222 {
223     const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
224     fprintf(stderr, message);
225     fprintf(stdout, message);
226     dump();
227 }
228
229 void LayoutTestController::setWaitToDump(bool waitUntilDone)
230 {
231     m_waitToDump = waitUntilDone;
232     if (m_waitToDump && !waitToDumpWatchdog)
233         waitToDumpWatchdog = CFRunLoopTimerCreate(kCFAllocatorDefault, 0, waitToDumpWatchdogInterval, 0, 0, waitUntilDoneWatchdogFired, NULL);
234 }
235
236 int LayoutTestController::windowCount()
237 {
238     return CFArrayGetCount(allWindowsRef);
239 }