2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #include "DumpRenderTree.h"
30 #include "LayoutTestController.h"
32 #include "EditingDelegate.h"
33 #include "PolicyDelegate.h"
34 #include "WorkQueue.h"
35 #include "WorkQueueItem.h"
36 #include <WebCore/COMPtr.h>
37 #include <wtf/Platform.h>
38 #include <wtf/RetainPtr.h>
39 #include <wtf/Vector.h>
40 #include <JavaScriptCore/Assertions.h>
41 #include <JavaScriptCore/JavaScriptCore.h>
42 #include <JavaScriptCore/JSRetainPtr.h>
43 #include <WebKit/IWebHistory.h>
44 #include <WebKit/IWebViewPrivate.h>
45 #include <WebKit/WebKit.h>
47 #include <CoreFoundation/CoreFoundation.h>
52 LayoutTestController::~LayoutTestController()
54 COMPtr<IWebView> webView;
55 if (FAILED(frame->webView(&webView)))
58 // reset webview-related states back to default values in preparation for next test
60 COMPtr<IWebViewPrivate> viewPrivate;
61 if (SUCCEEDED(webView->QueryInterface(&viewPrivate)))
62 viewPrivate->setTabKeyCyclesThroughElements(TRUE);
64 COMPtr<IWebViewEditing> viewEditing;
65 if (FAILED(webView->QueryInterface(&viewEditing)))
67 COMPtr<IWebEditingDelegate> delegate;
68 if (FAILED(viewEditing->editingDelegate(&delegate)))
70 COMPtr<EditingDelegate> editingDelegate(Query, viewEditing.get());
72 editingDelegate->setAcceptsEditing(TRUE);
75 void LayoutTestController::addDisallowedURL(JSStringRef url)
80 void LayoutTestController::clearBackForwardList()
82 COMPtr<IWebView> webView;
83 if (FAILED(frame->webView(&webView)))
86 COMPtr<IWebBackForwardList> backForwardList;
87 if (FAILED(webView->backForwardList(&backForwardList)))
90 COMPtr<IWebHistoryItem> item;
91 if (FAILED(backForwardList->currentItem(&item)))
94 // We clear the history by setting the back/forward list's capacity to 0
95 // then restoring it back and adding back the current item.
97 if (FAILED(backForwardList->capacity(&capacity)))
100 backForwardList->setCapacity(0);
101 backForwardList->setCapacity(capacity);
102 backForwardList->addItem(item.get());
103 backForwardList->goToItem(item.get());
106 JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name)
112 JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name)
118 void LayoutTestController::display()
123 void LayoutTestController::keepWebHistory()
125 COMPtr<IWebHistory> history(Create, CLSID_WebHistory);
129 COMPtr<IWebHistory> sharedHistory(Create, CLSID_WebHistory);
133 history->setOptionalSharedHistory(sharedHistory.get());
136 void LayoutTestController::notifyDone()
138 // Same as on mac. This can be shared.
139 if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
141 m_waitToDump = false;
144 void LayoutTestController::queueBackNavigation(int howFarBack)
146 // Same as on mac. This can be shared.
147 WorkQueue::shared()->queue(new BackItem(howFarBack));
150 void LayoutTestController::queueForwardNavigation(int howFarForward)
152 // Same as on mac. This can be shared.
153 WorkQueue::shared()->queue(new ForwardItem(howFarForward));
156 static wstring jsStringRefToWString(JSStringRef jsStr)
158 size_t length = JSStringGetLength(jsStr);
159 Vector<WCHAR> buffer(length + 1);
160 memcpy(buffer.data(), JSStringGetCharactersPtr(jsStr), length * sizeof(WCHAR));
161 buffer[length] = '\0';
163 return buffer.data();
166 void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
168 COMPtr<IWebDataSource> dataSource;
169 if (FAILED(frame->dataSource(&dataSource)))
172 COMPtr<IWebURLResponse> response;
173 if (FAILED(dataSource->response(&response)) || !response)
176 BSTR responseURLBSTR;
177 if (FAILED(response->URL(&responseURLBSTR)))
179 wstring responseURL(responseURLBSTR, SysStringLen(responseURLBSTR));
180 SysFreeString(responseURLBSTR);
182 // FIXME: We should do real relative URL resolution here.
183 int lastSlash = responseURL.rfind('/');
185 responseURL = responseURL.substr(0, lastSlash);
187 wstring wURL = jsStringRefToWString(url);
188 wstring wAbosuluteURL = responseURL + TEXT("/") + wURL;
189 JSRetainPtr<JSStringRef> jsAbsoluteURL(Adopt, JSStringCreateWithCharacters(wAbosuluteURL.data(), wAbosuluteURL.length()));
191 WorkQueue::shared()->queue(new LoadItem(jsAbsoluteURL.get(), target));
194 void LayoutTestController::queueReload()
196 WorkQueue::shared()->queue(new ReloadItem);
199 void LayoutTestController::queueScript(JSStringRef script)
201 WorkQueue::shared()->queue(new ScriptItem(script));
204 void LayoutTestController::setAcceptsEditing(bool acceptsEditing)
206 COMPtr<IWebView> webView;
207 if (FAILED(frame->webView(&webView)))
210 COMPtr<IWebViewEditing> viewEditing;
211 if (FAILED(webView->QueryInterface(&viewEditing)))
214 COMPtr<IWebEditingDelegate> delegate;
215 if (FAILED(viewEditing->editingDelegate(&delegate)))
218 EditingDelegate* editingDelegate = (EditingDelegate*)(IWebEditingDelegate*)delegate.get();
219 editingDelegate->setAcceptsEditing(acceptsEditing);
222 void LayoutTestController::setCustomPolicyDelegate(bool setDelegate)
224 COMPtr<IWebView> webView;
225 if (FAILED(frame->webView(&webView)))
229 webView->setPolicyDelegate(policyDelegate);
231 webView->setPolicyDelegate(NULL);
234 void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
239 void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
241 COMPtr<IWebView> webView;
242 if (FAILED(frame->webView(&webView)))
245 COMPtr<IWebPreferences> preferences;
246 if (FAILED(webView->preferences(&preferences)))
249 preferences->setPrivateBrowsingEnabled(privateBrowsingEnabled);
252 void LayoutTestController::setTabKeyCyclesThroughElements(bool shouldCycle)
254 COMPtr<IWebView> webView;
255 if (FAILED(frame->webView(&webView)))
258 COMPtr<IWebViewPrivate> viewPrivate;
259 if (FAILED(webView->QueryInterface(&viewPrivate)))
262 viewPrivate->setTabKeyCyclesThroughElements(shouldCycle ? TRUE : FALSE);
265 void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
270 void LayoutTestController::setUserStyleSheetEnabled(bool flag)
275 void LayoutTestController::setUserStyleSheetLocation(JSStringRef path)
280 void LayoutTestController::setWindowIsKey(bool flag)
285 static const CFTimeInterval waitToDumpWatchdogInterval = 10.0;
287 static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)
289 const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
290 fprintf(stderr, message);
291 fprintf(stdout, message);
295 void LayoutTestController::setWaitToDump(bool waitUntilDone)
297 // Same as on mac. This can be shared.
298 m_waitToDump = waitUntilDone;
299 if (m_waitToDump && !waitToDumpWatchdog)
300 ::waitToDumpWatchdog = CFRunLoopTimerCreate(0, 0, waitToDumpWatchdogInterval, 0, 0, waitUntilDoneWatchdogFired, NULL);
303 int LayoutTestController::windowCount()