1 /*
2 * Copyright (C) 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
4 * Copyright (C) 2008 Nuanti Ltd.
5 * Copyright (C) 2009 Jan Michael Alonzo <jmalonzo@gmail.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "config.h"
33 #include "LayoutTestController.h"
34
35 #include "DumpRenderTree.h"
36 #include "WorkQueue.h"
37 #include "WorkQueueItem.h"
38 #include <JavaScriptCore/JSRetainPtr.h>
39 #include <JavaScriptCore/JSStringRef.h>
40
41 #include <stdio.h>
42 #include <glib.h>
43 #include <libsoup/soup.h>
44 #include <webkit/webkit.h>
45
46 extern "C" {
47 bool webkit_web_frame_pause_animation(WebKitWebFrame* frame, const gchar* name, double time, const gchar* element);
48 bool webkit_web_frame_pause_transition(WebKitWebFrame* frame, const gchar* name, double time, const gchar* element);
49 unsigned int webkit_web_frame_number_of_active_animations(WebKitWebFrame* frame);
50 void webkit_application_cache_set_maximum_size(unsigned long long size);
51 }
52
~LayoutTestController()53 LayoutTestController::~LayoutTestController()
54 {
55 // FIXME: implement
56 }
57
addDisallowedURL(JSStringRef url)58 void LayoutTestController::addDisallowedURL(JSStringRef url)
59 {
60 // FIXME: implement
61 }
62
clearBackForwardList()63 void LayoutTestController::clearBackForwardList()
64 {
65 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
66 WebKitWebBackForwardList* list = webkit_web_view_get_back_forward_list(webView);
67 WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_current_item(list);
68 g_object_ref(item);
69
70 // We clear the history by setting the back/forward list's capacity to 0
71 // then restoring it back and adding back the current item.
72 gint limit = webkit_web_back_forward_list_get_limit(list);
73 webkit_web_back_forward_list_set_limit(list, 0);
74 webkit_web_back_forward_list_set_limit(list, limit);
75 webkit_web_back_forward_list_add_item(list, item);
76 webkit_web_back_forward_list_go_to_item(list, item);
77 g_object_unref(item);
78 }
79
copyDecodedHostName(JSStringRef name)80 JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name)
81 {
82 // FIXME: implement
83 return 0;
84 }
85
copyEncodedHostName(JSStringRef name)86 JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name)
87 {
88 // FIXME: implement
89 return 0;
90 }
91
dispatchPendingLoadRequests()92 void LayoutTestController::dispatchPendingLoadRequests()
93 {
94 // FIXME: Implement for testing fix for 6727495
95 }
96
display()97 void LayoutTestController::display()
98 {
99 displayWebView();
100 }
101
keepWebHistory()102 void LayoutTestController::keepWebHistory()
103 {
104 // FIXME: implement
105 }
106
webHistoryItemCount()107 size_t LayoutTestController::webHistoryItemCount()
108 {
109 // FIXME: implement
110 return 0;
111 }
112
notifyDone()113 void LayoutTestController::notifyDone()
114 {
115 if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
116 dump();
117 m_waitToDump = false;
118 waitForPolicy = false;
119 }
120
pathToLocalResource(JSContextRef context,JSStringRef url)121 JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url)
122 {
123 // Function introduced in r28690. This may need special-casing on Windows.
124 return JSStringRetain(url); // Do nothing on Unix.
125 }
126
queueLoad(JSStringRef url,JSStringRef target)127 void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
128 {
129 gchar* relativeURL = JSStringCopyUTF8CString(url);
130 SoupURI* baseURI = soup_uri_new(webkit_web_frame_get_uri(mainFrame));
131
132 SoupURI* absoluteURI = soup_uri_new_with_base(baseURI, relativeURL);
133 soup_uri_free(baseURI);
134 g_free(relativeURL);
135
136 gchar* absoluteCString;
137 if (absoluteURI) {
138 absoluteCString = soup_uri_to_string(absoluteURI, FALSE);
139 soup_uri_free(absoluteURI);
140 } else
141 absoluteCString = JSStringCopyUTF8CString(url);
142
143 JSRetainPtr<JSStringRef> absoluteURL(Adopt, JSStringCreateWithUTF8CString(absoluteCString));
144 g_free(absoluteCString);
145
146 WorkQueue::shared()->queue(new LoadItem(absoluteURL.get(), target));
147 }
148
setAcceptsEditing(bool acceptsEditing)149 void LayoutTestController::setAcceptsEditing(bool acceptsEditing)
150 {
151 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
152 webkit_web_view_set_editable(webView, acceptsEditing);
153 }
154
setCustomPolicyDelegate(bool setDelegate,bool permissive)155 void LayoutTestController::setCustomPolicyDelegate(bool setDelegate, bool permissive)
156 {
157 // FIXME: implement
158 }
159
waitForPolicyDelegate()160 void LayoutTestController::waitForPolicyDelegate()
161 {
162 waitForPolicy = true;
163 setWaitToDump(true);
164 }
165
setMainFrameIsFirstResponder(bool flag)166 void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
167 {
168 // FIXME: implement
169 }
170
setTabKeyCyclesThroughElements(bool cycles)171 void LayoutTestController::setTabKeyCyclesThroughElements(bool cycles)
172 {
173 // FIXME: implement
174 }
175
setUseDashboardCompatibilityMode(bool flag)176 void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
177 {
178 // FIXME: implement
179 }
180
181 static gchar* userStyleSheet = NULL;
182 static gboolean userStyleSheetEnabled = TRUE;
183
setUserStyleSheetEnabled(bool flag)184 void LayoutTestController::setUserStyleSheetEnabled(bool flag)
185 {
186 userStyleSheetEnabled = flag;
187
188 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame);
189 WebKitWebSettings* settings = webkit_web_view_get_settings(webView);
190 if (flag && userStyleSheet)
191 g_object_set(G_OBJECT(settings), "user-stylesheet-uri", userStyleSheet, NULL);
192 else
193 g_object_set(G_OBJECT(settings), "user-stylesheet-uri", "", NULL);
194 }
195
setUserStyleSheetLocation(JSStringRef path)196 void LayoutTestController::setUserStyleSheetLocation(JSStringRef path)
197 {
198 g_free(userStyleSheet);
199 userStyleSheet = JSStringCopyUTF8CString(path);
200 if (userStyleSheetEnabled)
201 setUserStyleSheetEnabled(true);
202 }
203
setWindowIsKey(bool windowIsKey)204 void LayoutTestController::setWindowIsKey(bool windowIsKey)
205 {
206 // FIXME: implement
207 }
208
setSmartInsertDeleteEnabled(bool flag)209 void LayoutTestController::setSmartInsertDeleteEnabled(bool flag)
210 {
211 // FIXME: implement
212 }
213
waitToDumpWatchdogFired(void *)214 static gboolean waitToDumpWatchdogFired(void*)
215 {
216 const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
217 fprintf(stderr, "%s", message);
218 fprintf(stdout, "%s", message);
219 waitToDumpWatchdog = 0;
220 dump();
221 return FALSE;
222 }
223
setWaitToDump(bool waitUntilDone)224 void LayoutTestController::setWaitToDump(bool waitUntilDone)
225 {
226 static const int timeoutSeconds = 10;
227
228 m_waitToDump = waitUntilDone;
229 if (m_waitToDump && !waitToDumpWatchdog)
230 waitToDumpWatchdog = g_timeout_add_seconds(timeoutSeconds, waitToDumpWatchdogFired, 0);
231 }
232
windowCount()233 int LayoutTestController::windowCount()
234 {
235 // +1 -> including the main view
236 return g_slist_length(webViewList) + 1;
237 }
238
setPrivateBrowsingEnabled(bool flag)239 void LayoutTestController::setPrivateBrowsingEnabled(bool flag)
240 {
241 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
242 ASSERT(view);
243
244 WebKitWebSettings* settings = webkit_web_view_get_settings(view);
245 g_object_set(G_OBJECT(settings), "enable-private-browsing", flag, NULL);
246 }
247
setXSSAuditorEnabled(bool flag)248 void LayoutTestController::setXSSAuditorEnabled(bool flag)
249 {
250 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
251 ASSERT(view);
252
253 WebKitWebSettings* settings = webkit_web_view_get_settings(view);
254 g_object_set(G_OBJECT(settings), "enable-xss-auditor", flag, NULL);
255 }
256
setAuthorAndUserStylesEnabled(bool flag)257 void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag)
258 {
259 // FIXME: implement
260 }
261
disableImageLoading()262 void LayoutTestController::disableImageLoading()
263 {
264 // FIXME: Implement for testing fix for https://bugs.webkit.org/show_bug.cgi?id=27896
265 // Also need to make sure image loading is re-enabled for each new test.
266 }
267
setIconDatabaseEnabled(bool flag)268 void LayoutTestController::setIconDatabaseEnabled(bool flag)
269 {
270 // FIXME: implement
271 }
272
setJavaScriptProfilingEnabled(bool flag)273 void LayoutTestController::setJavaScriptProfilingEnabled(bool flag)
274 {
275 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
276 ASSERT(view);
277
278 WebKitWebSettings* settings = webkit_web_view_get_settings(view);
279 g_object_set(G_OBJECT(settings), "enable-developer-extras", flag, NULL);
280
281 WebKitWebInspector* inspector = webkit_web_view_get_inspector(view);
282 g_object_set(G_OBJECT(inspector), "javascript-profiling-enabled", flag, NULL);
283 }
284
setSelectTrailingWhitespaceEnabled(bool flag)285 void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag)
286 {
287 // FIXME: implement
288 }
289
setPopupBlockingEnabled(bool flag)290 void LayoutTestController::setPopupBlockingEnabled(bool flag)
291 {
292 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
293 ASSERT(view);
294
295 WebKitWebSettings* settings = webkit_web_view_get_settings(view);
296 g_object_set(G_OBJECT(settings), "javascript-can-open-windows-automatically", !flag, NULL);
297
298 }
299
elementDoesAutoCompleteForElementWithId(JSStringRef id)300 bool LayoutTestController::elementDoesAutoCompleteForElementWithId(JSStringRef id)
301 {
302 // FIXME: implement
303 return false;
304 }
305
execCommand(JSStringRef name,JSStringRef value)306 void LayoutTestController::execCommand(JSStringRef name, JSStringRef value)
307 {
308 // FIXME: implement
309 }
310
setCacheModel(int)311 void LayoutTestController::setCacheModel(int)
312 {
313 // FIXME: implement
314 }
315
isCommandEnabled(JSStringRef)316 bool LayoutTestController::isCommandEnabled(JSStringRef /*name*/)
317 {
318 // FIXME: implement
319 return false;
320 }
321
setPersistentUserStyleSheetLocation(JSStringRef jsURL)322 void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL)
323 {
324 // FIXME: implement
325 }
326
clearPersistentUserStyleSheet()327 void LayoutTestController::clearPersistentUserStyleSheet()
328 {
329 // FIXME: implement
330 }
331
clearAllDatabases()332 void LayoutTestController::clearAllDatabases()
333 {
334 // FIXME: implement
335 }
336
setDatabaseQuota(unsigned long long quota)337 void LayoutTestController::setDatabaseQuota(unsigned long long quota)
338 {
339 // FIXME: implement
340 }
341
setAppCacheMaximumSize(unsigned long long size)342 void LayoutTestController::setAppCacheMaximumSize(unsigned long long size)
343 {
344 webkit_application_cache_set_maximum_size(size);
345 }
346
pauseAnimationAtTimeOnElementWithId(JSStringRef animationName,double time,JSStringRef elementId)347 bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId)
348 {
349 gchar* name = JSStringCopyUTF8CString(animationName);
350 gchar* element = JSStringCopyUTF8CString(elementId);
351 return webkit_web_frame_pause_animation(mainFrame, name, time, element);
352 }
353
pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName,double time,JSStringRef elementId)354 bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName, double time, JSStringRef elementId)
355 {
356 gchar* name = JSStringCopyUTF8CString(propertyName);
357 gchar* element = JSStringCopyUTF8CString(elementId);
358 return webkit_web_frame_pause_transition(mainFrame, name, time, element);
359 }
360
numberOfActiveAnimations() const361 unsigned LayoutTestController::numberOfActiveAnimations() const
362 {
363 return webkit_web_frame_number_of_active_animations(mainFrame);
364 }
365