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/IWebViewPrivate.h>
45 #include <CoreFoundation/CoreFoundation.h>
50 LayoutTestController::~LayoutTestController()
52 COMPtr<IWebView> webView;
53 if (FAILED(frame->webView(&webView)))
56 // reset webview-related states back to default values in preparation for next test
58 COMPtr<IWebViewPrivate> viewPrivate;
59 if (SUCCEEDED(webView->QueryInterface(&viewPrivate)))
60 viewPrivate->setTabKeyCyclesThroughElements(TRUE);
62 COMPtr<IWebViewEditing> viewEditing;
63 if (FAILED(webView->QueryInterface(&viewEditing)))
65 COMPtr<IWebEditingDelegate> delegate;
66 if (FAILED(viewEditing->editingDelegate(&delegate)))
68 COMPtr<EditingDelegate> editingDelegate(Query, viewEditing.get());
70 editingDelegate->setAcceptsEditing(TRUE);
73 void LayoutTestController::addDisallowedURL(JSStringRef url)
78 void LayoutTestController::clearBackForwardList()
80 COMPtr<IWebView> webView;
81 if (FAILED(frame->webView(&webView)))
84 COMPtr<IWebBackForwardList> backForwardList;
85 if (FAILED(webView->backForwardList(&backForwardList)))
88 COMPtr<IWebHistoryItem> item;
89 if (FAILED(backForwardList->currentItem(&item)))
92 // We clear the history by setting the back/forward list's capacity to 0
93 // then restoring it back and adding back the current item.
95 if (FAILED(backForwardList->capacity(&capacity)))
98 backForwardList->setCapacity(0);
99 backForwardList->setCapacity(capacity);
100 backForwardList->addItem(item.get());
101 backForwardList->goToItem(item.get());
104 JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name)
110 JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name)
116 void LayoutTestController::display()
121 void LayoutTestController::keepWebHistory()
126 void LayoutTestController::notifyDone()
128 // Same as on mac. This can be shared.
129 if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
131 m_waitToDump = false;
134 void LayoutTestController::queueBackNavigation(int howFarBack)
136 // Same as on mac. This can be shared.
137 WorkQueue::shared()->queue(new BackItem(howFarBack));
140 void LayoutTestController::queueForwardNavigation(int howFarForward)
142 // Same as on mac. This can be shared.
143 WorkQueue::shared()->queue(new ForwardItem(howFarForward));
146 static wstring jsStringRefToWString(JSStringRef jsStr)
148 size_t length = JSStringGetLength(jsStr);
149 Vector<WCHAR> buffer(length + 1);
150 memcpy(buffer.data(), JSStringGetCharactersPtr(jsStr), length * sizeof(WCHAR));
151 buffer[length] = '\0';
153 return buffer.data();
156 void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
158 COMPtr<IWebDataSource> dataSource;
159 if (FAILED(frame->dataSource(&dataSource)))
162 COMPtr<IWebURLResponse> response;
163 if (FAILED(dataSource->response(&response)) || !response)
166 BSTR responseURLBSTR;
167 if (FAILED(response->URL(&responseURLBSTR)))
169 wstring responseURL(responseURLBSTR, SysStringLen(responseURLBSTR));
170 SysFreeString(responseURLBSTR);
172 // FIXME: We should do real relative URL resolution here.
173 int lastSlash = responseURL.rfind('/');
175 responseURL = responseURL.substr(0, lastSlash);
177 wstring wURL = jsStringRefToWString(url);
178 wstring wAbosuluteURL = responseURL + TEXT("/") + wURL;
179 JSRetainPtr<JSStringRef> jsAbsoluteURL(Adopt, JSStringCreateWithCharacters(wAbosuluteURL.data(), wAbosuluteURL.length()));
181 WorkQueue::shared()->queue(new LoadItem(jsAbsoluteURL.get(), target));
184 void LayoutTestController::queueReload()
186 WorkQueue::shared()->queue(new ReloadItem);
189 void LayoutTestController::queueScript(JSStringRef script)
191 WorkQueue::shared()->queue(new ScriptItem(script));
194 void LayoutTestController::setAcceptsEditing(bool acceptsEditing)
196 COMPtr<IWebView> webView;
197 if (FAILED(frame->webView(&webView)))
200 COMPtr<IWebViewEditing> viewEditing;
201 if (FAILED(webView->QueryInterface(&viewEditing)))
204 COMPtr<IWebEditingDelegate> delegate;
205 if (FAILED(viewEditing->editingDelegate(&delegate)))
208 EditingDelegate* editingDelegate = (EditingDelegate*)(IWebEditingDelegate*)delegate.get();
209 editingDelegate->setAcceptsEditing(acceptsEditing);
212 void LayoutTestController::setCustomPolicyDelegate(bool setDelegate)
214 COMPtr<IWebView> webView;
215 if (FAILED(frame->webView(&webView)))
219 webView->setPolicyDelegate(policyDelegate);
221 webView->setPolicyDelegate(NULL);
224 void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
229 void LayoutTestController::setPrivateBrowsingEnabled(bool /*privateBrowsingEnabled*/)
234 void LayoutTestController::setTabKeyCyclesThroughElements(bool shouldCycle)
236 COMPtr<IWebView> webView;
237 if (FAILED(frame->webView(&webView)))
240 COMPtr<IWebViewPrivate> viewPrivate;
241 if (FAILED(webView->QueryInterface(&viewPrivate)))
244 viewPrivate->setTabKeyCyclesThroughElements(shouldCycle ? TRUE : FALSE);
247 void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
252 void LayoutTestController::setUserStyleSheetEnabled(bool flag)
257 void LayoutTestController::setUserStyleSheetLocation(JSStringRef path)
262 void LayoutTestController::setWindowIsKey(bool flag)
267 static const CFTimeInterval waitToDumpWatchdogInterval = 10.0;
269 static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)
271 const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
272 fprintf(stderr, message);
273 fprintf(stdout, message);
277 void LayoutTestController::setWaitToDump(bool waitUntilDone)
279 // Same as on mac. This can be shared.
280 m_waitToDump = waitUntilDone;
281 if (m_waitToDump && !waitToDumpWatchdog)
282 ::waitToDumpWatchdog = CFRunLoopTimerCreate(0, 0, waitToDumpWatchdogInterval, 0, 0, waitUntilDoneWatchdogFired, NULL);
285 int LayoutTestController::windowCount()