1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * Copyright (C) 2010 Pawel Hajdan (phajdan.jr@chromium.org)
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "config.h"
33 #include "LayoutTestController.h"
34
35 #include "DRTDevToolsAgent.h"
36 #include "TestShell.h"
37 #include "WebAnimationController.h"
38 #include "WebBindings.h"
39 #include "WebConsoleMessage.h"
40 #include "WebData.h"
41 #include "WebDeviceOrientation.h"
42 #include "WebDeviceOrientationClientMock.h"
43 #include "WebDocument.h"
44 #include "WebElement.h"
45 #include "WebFrame.h"
46 #include "WebGeolocationClientMock.h"
47 #include "WebInputElement.h"
48 #include "WebKit.h"
49 #include "WebNotificationPresenter.h"
50 #include "WebScriptSource.h"
51 #include "WebSecurityPolicy.h"
52 #include "WebSettings.h"
53 #include "WebSize.h"
54 #include "WebSpeechInputControllerMock.h"
55 #include "WebURL.h"
56 #include "WebView.h"
57 #include "WebViewHost.h"
58 #include "webkit/support/webkit_support.h"
59 #include <algorithm>
60 #include <cstdlib>
61 #include <limits>
62 #include <wtf/text/WTFString.h>
63
64 #if OS(WINDOWS)
65 #include <wtf/OwnArrayPtr.h>
66 #endif
67
68 using namespace WebCore;
69 using namespace WebKit;
70 using namespace std;
71
LayoutTestController(TestShell * shell)72 LayoutTestController::LayoutTestController(TestShell* shell)
73 : m_shell(shell)
74 , m_closeRemainingWindows(false)
75 , m_deferMainResourceDataLoad(false)
76 , m_showDebugLayerTree(false)
77 , m_workQueue(this)
78 {
79
80 // Initialize the map that associates methods of this class with the names
81 // they will use when called by JavaScript. The actual binding of those
82 // names to their methods will be done by calling bindToJavaScript() (defined
83 // by CppBoundClass, the parent to LayoutTestController).
84 bindMethod("addFileToPasteboardOnDrag", &LayoutTestController::addFileToPasteboardOnDrag);
85 bindMethod("addOriginAccessWhitelistEntry", &LayoutTestController::addOriginAccessWhitelistEntry);
86 bindMethod("addUserScript", &LayoutTestController::addUserScript);
87 bindMethod("addUserStyleSheet", &LayoutTestController::addUserStyleSheet);
88 bindMethod("clearAllDatabases", &LayoutTestController::clearAllDatabases);
89 bindMethod("closeWebInspector", &LayoutTestController::closeWebInspector);
90 bindMethod("counterValueForElementById", &LayoutTestController::counterValueForElementById);
91 bindMethod("disableImageLoading", &LayoutTestController::disableImageLoading);
92 bindMethod("display", &LayoutTestController::display);
93 bindMethod("displayInvalidatedRegion", &LayoutTestController::displayInvalidatedRegion);
94 bindMethod("dumpAsText", &LayoutTestController::dumpAsText);
95 bindMethod("dumpBackForwardList", &LayoutTestController::dumpBackForwardList);
96 bindMethod("dumpChildFramesAsText", &LayoutTestController::dumpChildFramesAsText);
97 bindMethod("dumpChildFrameScrollPositions", &LayoutTestController::dumpChildFrameScrollPositions);
98 bindMethod("dumpDatabaseCallbacks", &LayoutTestController::dumpDatabaseCallbacks);
99 bindMethod("dumpEditingCallbacks", &LayoutTestController::dumpEditingCallbacks);
100 bindMethod("dumpFrameLoadCallbacks", &LayoutTestController::dumpFrameLoadCallbacks);
101 bindMethod("dumpUserGestureInFrameLoadCallbacks", &LayoutTestController::dumpUserGestureInFrameLoadCallbacks);
102 bindMethod("dumpResourceLoadCallbacks", &LayoutTestController::dumpResourceLoadCallbacks);
103 bindMethod("dumpResourceResponseMIMETypes", &LayoutTestController::dumpResourceResponseMIMETypes);
104 bindMethod("dumpSelectionRect", &LayoutTestController::dumpSelectionRect);
105 bindMethod("dumpStatusCallbacks", &LayoutTestController::dumpWindowStatusChanges);
106 bindMethod("dumpTitleChanges", &LayoutTestController::dumpTitleChanges);
107 bindMethod("elementDoesAutoCompleteForElementWithId", &LayoutTestController::elementDoesAutoCompleteForElementWithId);
108 bindMethod("evaluateInWebInspector", &LayoutTestController::evaluateInWebInspector);
109 bindMethod("evaluateScriptInIsolatedWorld", &LayoutTestController::evaluateScriptInIsolatedWorld);
110 bindMethod("execCommand", &LayoutTestController::execCommand);
111 bindMethod("grantDesktopNotificationPermission", &LayoutTestController::grantDesktopNotificationPermission);
112 bindMethod("hasSpellingMarker", &LayoutTestController::hasSpellingMarker);
113 bindMethod("isCommandEnabled", &LayoutTestController::isCommandEnabled);
114 bindMethod("layerTreeAsText", &LayoutTestController::layerTreeAsText);
115 bindMethod("markerTextForListItem", &LayoutTestController::markerTextForListItem);
116 bindMethod("notifyDone", &LayoutTestController::notifyDone);
117 bindMethod("numberOfActiveAnimations", &LayoutTestController::numberOfActiveAnimations);
118 bindMethod("numberOfPages", &LayoutTestController::numberOfPages);
119 bindMethod("numberOfPendingGeolocationPermissionRequests", &LayoutTestController:: numberOfPendingGeolocationPermissionRequests);
120 bindMethod("objCIdentityIsEqual", &LayoutTestController::objCIdentityIsEqual);
121 bindMethod("overridePreference", &LayoutTestController::overridePreference);
122 bindMethod("pageNumberForElementById", &LayoutTestController::pageNumberForElementById);
123 bindMethod("pathToLocalResource", &LayoutTestController::pathToLocalResource);
124 bindMethod("pauseAnimationAtTimeOnElementWithId", &LayoutTestController::pauseAnimationAtTimeOnElementWithId);
125 bindMethod("pauseTransitionAtTimeOnElementWithId", &LayoutTestController::pauseTransitionAtTimeOnElementWithId);
126 bindMethod("queueBackNavigation", &LayoutTestController::queueBackNavigation);
127 bindMethod("queueForwardNavigation", &LayoutTestController::queueForwardNavigation);
128 bindMethod("queueLoadingScript", &LayoutTestController::queueLoadingScript);
129 bindMethod("queueLoad", &LayoutTestController::queueLoad);
130 bindMethod("queueLoadHTMLString", &LayoutTestController::queueLoadHTMLString);
131 bindMethod("queueNonLoadingScript", &LayoutTestController::queueNonLoadingScript);
132 bindMethod("queueReload", &LayoutTestController::queueReload);
133 bindMethod("removeOriginAccessWhitelistEntry", &LayoutTestController::removeOriginAccessWhitelistEntry);
134 bindMethod("repaintSweepHorizontally", &LayoutTestController::repaintSweepHorizontally);
135 bindMethod("resumeAnimations", &LayoutTestController::resumeAnimations);
136 bindMethod("sampleSVGAnimationForElementAtTime", &LayoutTestController::sampleSVGAnimationForElementAtTime);
137 bindMethod("setAcceptsEditing", &LayoutTestController::setAcceptsEditing);
138 bindMethod("setAllowFileAccessFromFileURLs", &LayoutTestController::setAllowFileAccessFromFileURLs);
139 bindMethod("setAllowUniversalAccessFromFileURLs", &LayoutTestController::setAllowUniversalAccessFromFileURLs);
140 bindMethod("setAlwaysAcceptCookies", &LayoutTestController::setAlwaysAcceptCookies);
141 bindMethod("setAuthorAndUserStylesEnabled", &LayoutTestController::setAuthorAndUserStylesEnabled);
142 bindMethod("setAutofilled", &LayoutTestController::setAutofilled);
143 bindMethod("setCanOpenWindows", &LayoutTestController::setCanOpenWindows);
144 bindMethod("setCloseRemainingWindowsWhenComplete", &LayoutTestController::setCloseRemainingWindowsWhenComplete);
145 bindMethod("setCustomPolicyDelegate", &LayoutTestController::setCustomPolicyDelegate);
146 bindMethod("setDatabaseQuota", &LayoutTestController::setDatabaseQuota);
147 bindMethod("setDeferMainResourceDataLoad", &LayoutTestController::setDeferMainResourceDataLoad);
148 bindMethod("setDomainRelaxationForbiddenForURLScheme", &LayoutTestController::setDomainRelaxationForbiddenForURLScheme);
149 bindMethod("setEditingBehavior", &LayoutTestController::setEditingBehavior);
150 bindMethod("setGeolocationPermission", &LayoutTestController::setGeolocationPermission);
151 bindMethod("setIconDatabaseEnabled", &LayoutTestController::setIconDatabaseEnabled);
152 bindMethod("setJavaScriptCanAccessClipboard", &LayoutTestController::setJavaScriptCanAccessClipboard);
153 bindMethod("setMinimumTimerInterval", &LayoutTestController::setMinimumTimerInterval);
154 bindMethod("setMockDeviceOrientation", &LayoutTestController::setMockDeviceOrientation);
155 bindMethod("setMockGeolocationError", &LayoutTestController::setMockGeolocationError);
156 bindMethod("setMockGeolocationPosition", &LayoutTestController::setMockGeolocationPosition);
157 bindMethod("addMockSpeechInputResult", &LayoutTestController::addMockSpeechInputResult);
158 bindMethod("setPluginsEnabled", &LayoutTestController::setPluginsEnabled);
159 bindMethod("setPopupBlockingEnabled", &LayoutTestController::setPopupBlockingEnabled);
160 bindMethod("setPOSIXLocale", &LayoutTestController::setPOSIXLocale);
161 bindMethod("setScrollbarPolicy", &LayoutTestController::setScrollbarPolicy);
162 bindMethod("setSelectTrailingWhitespaceEnabled", &LayoutTestController::setSelectTrailingWhitespaceEnabled);
163 bindMethod("setSmartInsertDeleteEnabled", &LayoutTestController::setSmartInsertDeleteEnabled);
164 bindMethod("setStopProvisionalFrameLoads", &LayoutTestController::setStopProvisionalFrameLoads);
165 bindMethod("setTabKeyCyclesThroughElements", &LayoutTestController::setTabKeyCyclesThroughElements);
166 bindMethod("setTimelineProfilingEnabled", &LayoutTestController::setTimelineProfilingEnabled);
167 bindMethod("setUserStyleSheetEnabled", &LayoutTestController::setUserStyleSheetEnabled);
168 bindMethod("setUserStyleSheetLocation", &LayoutTestController::setUserStyleSheetLocation);
169 bindMethod("setValueForUser", &LayoutTestController::setValueForUser);
170 bindMethod("setWillSendRequestClearHeader", &LayoutTestController::setWillSendRequestClearHeader);
171 bindMethod("setWillSendRequestReturnsNull", &LayoutTestController::setWillSendRequestReturnsNull);
172 bindMethod("setWillSendRequestReturnsNullOnRedirect", &LayoutTestController::setWillSendRequestReturnsNullOnRedirect);
173 bindMethod("setWindowIsKey", &LayoutTestController::setWindowIsKey);
174 bindMethod("setXSSAuditorEnabled", &LayoutTestController::setXSSAuditorEnabled);
175 bindMethod("setAsynchronousSpellCheckingEnabled", &LayoutTestController::setAsynchronousSpellCheckingEnabled);
176 bindMethod("shadowRoot", &LayoutTestController::shadowRoot);
177 bindMethod("showWebInspector", &LayoutTestController::showWebInspector);
178 bindMethod("simulateDesktopNotificationClick", &LayoutTestController::simulateDesktopNotificationClick);
179 bindMethod("suspendAnimations", &LayoutTestController::suspendAnimations);
180 bindMethod("testRepaint", &LayoutTestController::testRepaint);
181 bindMethod("waitForPolicyDelegate", &LayoutTestController::waitForPolicyDelegate);
182 bindMethod("waitUntilDone", &LayoutTestController::waitUntilDone);
183 bindMethod("windowCount", &LayoutTestController::windowCount);
184
185 // The following are stubs.
186 bindMethod("abortModal", &LayoutTestController::abortModal);
187 bindMethod("accessStoredWebScriptObject", &LayoutTestController::accessStoredWebScriptObject);
188 bindMethod("addDisallowedURL", &LayoutTestController::addDisallowedURL);
189 bindMethod("callShouldCloseOnWebView", &LayoutTestController::callShouldCloseOnWebView);
190 bindMethod("clearAllApplicationCaches", &LayoutTestController::clearAllApplicationCaches);
191 bindMethod("clearApplicationCacheForOrigin", &LayoutTestController::clearApplicationCacheForOrigin);
192 bindMethod("clearBackForwardList", &LayoutTestController::clearBackForwardList);
193 bindMethod("dumpAsWebArchive", &LayoutTestController::dumpAsWebArchive);
194 bindMethod("keepWebHistory", &LayoutTestController::keepWebHistory);
195 bindMethod("objCClassNameOf", &LayoutTestController::objCClassNameOf);
196 bindMethod("setApplicationCacheOriginQuota", &LayoutTestController::setApplicationCacheOriginQuota);
197 bindMethod("setCallCloseOnWebViews", &LayoutTestController::setCallCloseOnWebViews);
198 bindMethod("setMainFrameIsFirstResponder", &LayoutTestController::setMainFrameIsFirstResponder);
199 bindMethod("setPrivateBrowsingEnabled", &LayoutTestController::setPrivateBrowsingEnabled);
200 bindMethod("setUseDashboardCompatibilityMode", &LayoutTestController::setUseDashboardCompatibilityMode);
201 bindMethod("storeWebScriptObject", &LayoutTestController::storeWebScriptObject);
202 bindMethod("deleteAllLocalStorage", &LayoutTestController::deleteAllLocalStorage);
203 bindMethod("originsWithLocalStorage", &LayoutTestController::originsWithLocalStorage);
204 bindMethod("deleteLocalStorageForOrigin", &LayoutTestController::deleteLocalStorageForOrigin);
205 bindMethod("observeStorageTrackerNotifications", &LayoutTestController::observeStorageTrackerNotifications);
206 bindMethod("syncLocalStorage", &LayoutTestController::syncLocalStorage);
207
208 // The fallback method is called when an unknown method is invoked.
209 bindFallbackMethod(&LayoutTestController::fallbackMethod);
210
211 // Shared properties.
212 // globalFlag is used by a number of layout tests in
213 // LayoutTests\http\tests\security\dataURL.
214 bindProperty("globalFlag", &m_globalFlag);
215 // webHistoryItemCount is used by tests in LayoutTests\http\tests\history
216 bindProperty("webHistoryItemCount", &m_webHistoryItemCount);
217 bindProperty("titleTextDirection", &m_titleTextDirection);
218 }
219
~LayoutTestController()220 LayoutTestController::~LayoutTestController()
221 {
222 }
223
~WorkQueue()224 LayoutTestController::WorkQueue::~WorkQueue()
225 {
226 reset();
227 }
228
processWorkSoon()229 void LayoutTestController::WorkQueue::processWorkSoon()
230 {
231 if (m_controller->m_shell->webViewHost()->topLoadingFrame())
232 return;
233
234 if (!m_queue.isEmpty()) {
235 // We delay processing queued work to avoid recursion problems.
236 postTask(new WorkQueueTask(this));
237 } else if (!m_controller->m_waitUntilDone)
238 m_controller->m_shell->testFinished();
239 }
240
processWork()241 void LayoutTestController::WorkQueue::processWork()
242 {
243 TestShell* shell = m_controller->m_shell;
244 // Quit doing work once a load is in progress.
245 while (!m_queue.isEmpty()) {
246 bool startedLoad = m_queue.first()->run(shell);
247 delete m_queue.takeFirst();
248 if (startedLoad)
249 return;
250 }
251
252 if (!m_controller->m_waitUntilDone && !shell->webViewHost()->topLoadingFrame())
253 shell->testFinished();
254 }
255
reset()256 void LayoutTestController::WorkQueue::reset()
257 {
258 m_frozen = false;
259 while (!m_queue.isEmpty()) {
260 delete m_queue.takeFirst();
261 }
262 }
263
addWork(WorkItem * work)264 void LayoutTestController::WorkQueue::addWork(WorkItem* work)
265 {
266 if (m_frozen) {
267 delete work;
268 return;
269 }
270 m_queue.append(work);
271 }
272
dumpAsText(const CppArgumentList & arguments,CppVariant * result)273 void LayoutTestController::dumpAsText(const CppArgumentList& arguments, CppVariant* result)
274 {
275 m_dumpAsText = true;
276 m_generatePixelResults = false;
277
278 // Optional paramater, describing whether it's allowed to dump pixel results in dumpAsText mode.
279 if (arguments.size() > 0 && arguments[0].isBool())
280 m_generatePixelResults = arguments[0].value.boolValue;
281
282 result->setNull();
283 }
284
dumpDatabaseCallbacks(const CppArgumentList &,CppVariant * result)285 void LayoutTestController::dumpDatabaseCallbacks(const CppArgumentList&, CppVariant* result)
286 {
287 // Do nothing; we don't use this flag anywhere for now
288 result->setNull();
289 }
290
dumpEditingCallbacks(const CppArgumentList &,CppVariant * result)291 void LayoutTestController::dumpEditingCallbacks(const CppArgumentList&, CppVariant* result)
292 {
293 m_dumpEditingCallbacks = true;
294 result->setNull();
295 }
296
dumpBackForwardList(const CppArgumentList &,CppVariant * result)297 void LayoutTestController::dumpBackForwardList(const CppArgumentList&, CppVariant* result)
298 {
299 m_dumpBackForwardList = true;
300 result->setNull();
301 }
302
dumpFrameLoadCallbacks(const CppArgumentList &,CppVariant * result)303 void LayoutTestController::dumpFrameLoadCallbacks(const CppArgumentList&, CppVariant* result)
304 {
305 m_dumpFrameLoadCallbacks = true;
306 result->setNull();
307 }
308
dumpUserGestureInFrameLoadCallbacks(const CppArgumentList &,CppVariant * result)309 void LayoutTestController::dumpUserGestureInFrameLoadCallbacks(const CppArgumentList&, CppVariant* result)
310 {
311 m_dumpUserGestureInFrameLoadCallbacks = true;
312 result->setNull();
313 }
314
dumpResourceLoadCallbacks(const CppArgumentList &,CppVariant * result)315 void LayoutTestController::dumpResourceLoadCallbacks(const CppArgumentList&, CppVariant* result)
316 {
317 m_dumpResourceLoadCallbacks = true;
318 result->setNull();
319 }
320
dumpResourceResponseMIMETypes(const CppArgumentList &,CppVariant * result)321 void LayoutTestController::dumpResourceResponseMIMETypes(const CppArgumentList&, CppVariant* result)
322 {
323 m_dumpResourceResponseMIMETypes = true;
324 result->setNull();
325 }
326
dumpChildFrameScrollPositions(const CppArgumentList &,CppVariant * result)327 void LayoutTestController::dumpChildFrameScrollPositions(const CppArgumentList&, CppVariant* result)
328 {
329 m_dumpChildFrameScrollPositions = true;
330 result->setNull();
331 }
332
dumpChildFramesAsText(const CppArgumentList &,CppVariant * result)333 void LayoutTestController::dumpChildFramesAsText(const CppArgumentList&, CppVariant* result)
334 {
335 m_dumpChildFramesAsText = true;
336 result->setNull();
337 }
338
dumpWindowStatusChanges(const CppArgumentList &,CppVariant * result)339 void LayoutTestController::dumpWindowStatusChanges(const CppArgumentList&, CppVariant* result)
340 {
341 m_dumpWindowStatusChanges = true;
342 result->setNull();
343 }
344
dumpTitleChanges(const CppArgumentList &,CppVariant * result)345 void LayoutTestController::dumpTitleChanges(const CppArgumentList&, CppVariant* result)
346 {
347 m_dumpTitleChanges = true;
348 result->setNull();
349 }
350
setAcceptsEditing(const CppArgumentList & arguments,CppVariant * result)351 void LayoutTestController::setAcceptsEditing(const CppArgumentList& arguments, CppVariant* result)
352 {
353 if (arguments.size() > 0 && arguments[0].isBool())
354 m_acceptsEditing = arguments[0].value.boolValue;
355 result->setNull();
356 }
357
waitUntilDone(const CppArgumentList &,CppVariant * result)358 void LayoutTestController::waitUntilDone(const CppArgumentList&, CppVariant* result)
359 {
360 if (!webkit_support::BeingDebugged())
361 postDelayedTask(new NotifyDoneTimedOutTask(this), m_shell->layoutTestTimeout());
362 m_waitUntilDone = true;
363 result->setNull();
364 }
365
notifyDone(const CppArgumentList &,CppVariant * result)366 void LayoutTestController::notifyDone(const CppArgumentList&, CppVariant* result)
367 {
368 // Test didn't timeout. Kill the timeout timer.
369 m_taskList.revokeAll();
370
371 completeNotifyDone(false);
372 result->setNull();
373 }
374
completeNotifyDone(bool isTimeout)375 void LayoutTestController::completeNotifyDone(bool isTimeout)
376 {
377 if (m_waitUntilDone && !m_shell->webViewHost()->topLoadingFrame() && m_workQueue.isEmpty()) {
378 if (isTimeout)
379 m_shell->testTimedOut();
380 else
381 m_shell->testFinished();
382 }
383 m_waitUntilDone = false;
384 }
385
386 class WorkItemBackForward : public LayoutTestController::WorkItem {
387 public:
WorkItemBackForward(int distance)388 WorkItemBackForward(int distance) : m_distance(distance) {}
run(TestShell * shell)389 bool run(TestShell* shell)
390 {
391 shell->goToOffset(m_distance);
392 return true; // FIXME: Did it really start a navigation?
393 }
394 private:
395 int m_distance;
396 };
397
queueBackNavigation(const CppArgumentList & arguments,CppVariant * result)398 void LayoutTestController::queueBackNavigation(const CppArgumentList& arguments, CppVariant* result)
399 {
400 if (arguments.size() > 0 && arguments[0].isNumber())
401 m_workQueue.addWork(new WorkItemBackForward(-arguments[0].toInt32()));
402 result->setNull();
403 }
404
queueForwardNavigation(const CppArgumentList & arguments,CppVariant * result)405 void LayoutTestController::queueForwardNavigation(const CppArgumentList& arguments, CppVariant* result)
406 {
407 if (arguments.size() > 0 && arguments[0].isNumber())
408 m_workQueue.addWork(new WorkItemBackForward(arguments[0].toInt32()));
409 result->setNull();
410 }
411
412 class WorkItemReload : public LayoutTestController::WorkItem {
413 public:
run(TestShell * shell)414 bool run(TestShell* shell)
415 {
416 shell->reload();
417 return true;
418 }
419 };
420
queueReload(const CppArgumentList &,CppVariant * result)421 void LayoutTestController::queueReload(const CppArgumentList&, CppVariant* result)
422 {
423 m_workQueue.addWork(new WorkItemReload);
424 result->setNull();
425 }
426
427 class WorkItemLoadingScript : public LayoutTestController::WorkItem {
428 public:
WorkItemLoadingScript(const string & script)429 WorkItemLoadingScript(const string& script) : m_script(script) {}
run(TestShell * shell)430 bool run(TestShell* shell)
431 {
432 shell->webView()->mainFrame()->executeScript(WebScriptSource(WebString::fromUTF8(m_script)));
433 return true; // FIXME: Did it really start a navigation?
434 }
435 private:
436 string m_script;
437 };
438
439 class WorkItemNonLoadingScript : public LayoutTestController::WorkItem {
440 public:
WorkItemNonLoadingScript(const string & script)441 WorkItemNonLoadingScript(const string& script) : m_script(script) {}
run(TestShell * shell)442 bool run(TestShell* shell)
443 {
444 shell->webView()->mainFrame()->executeScript(WebScriptSource(WebString::fromUTF8(m_script)));
445 return false;
446 }
447 private:
448 string m_script;
449 };
450
queueLoadingScript(const CppArgumentList & arguments,CppVariant * result)451 void LayoutTestController::queueLoadingScript(const CppArgumentList& arguments, CppVariant* result)
452 {
453 if (arguments.size() > 0 && arguments[0].isString())
454 m_workQueue.addWork(new WorkItemLoadingScript(arguments[0].toString()));
455 result->setNull();
456 }
457
queueNonLoadingScript(const CppArgumentList & arguments,CppVariant * result)458 void LayoutTestController::queueNonLoadingScript(const CppArgumentList& arguments, CppVariant* result)
459 {
460 if (arguments.size() > 0 && arguments[0].isString())
461 m_workQueue.addWork(new WorkItemNonLoadingScript(arguments[0].toString()));
462 result->setNull();
463 }
464
465 class WorkItemLoad : public LayoutTestController::WorkItem {
466 public:
WorkItemLoad(const WebURL & url,const WebString & target)467 WorkItemLoad(const WebURL& url, const WebString& target)
468 : m_url(url)
469 , m_target(target) {}
run(TestShell * shell)470 bool run(TestShell* shell)
471 {
472 shell->webViewHost()->loadURLForFrame(m_url, m_target);
473 return true; // FIXME: Did it really start a navigation?
474 }
475 private:
476 WebURL m_url;
477 WebString m_target;
478 };
479
queueLoad(const CppArgumentList & arguments,CppVariant * result)480 void LayoutTestController::queueLoad(const CppArgumentList& arguments, CppVariant* result)
481 {
482 if (arguments.size() > 0 && arguments[0].isString()) {
483 // FIXME: Implement WebURL::resolve() and avoid GURL.
484 GURL currentURL = m_shell->webView()->mainFrame()->url();
485 GURL fullURL = currentURL.Resolve(arguments[0].toString());
486
487 string target = "";
488 if (arguments.size() > 1 && arguments[1].isString())
489 target = arguments[1].toString();
490
491 m_workQueue.addWork(new WorkItemLoad(fullURL, WebString::fromUTF8(target)));
492 }
493 result->setNull();
494 }
495
496 class WorkItemLoadHTMLString : public LayoutTestController::WorkItem {
497 public:
WorkItemLoadHTMLString(const std::string & html,const WebURL & baseURL)498 WorkItemLoadHTMLString(const std::string& html, const WebURL& baseURL)
499 : m_html(html)
500 , m_baseURL(baseURL) {}
WorkItemLoadHTMLString(const std::string & html,const WebURL & baseURL,const WebURL & unreachableURL)501 WorkItemLoadHTMLString(const std::string& html, const WebURL& baseURL, const WebURL& unreachableURL)
502 : m_html(html)
503 , m_baseURL(baseURL)
504 , m_unreachableURL(unreachableURL) {}
run(TestShell * shell)505 bool run(TestShell* shell)
506 {
507 shell->webView()->mainFrame()->loadHTMLString(
508 WebKit::WebData(m_html.data(), m_html.length()), m_baseURL, m_unreachableURL);
509 return true;
510 }
511 private:
512 std::string m_html;
513 WebURL m_baseURL;
514 WebURL m_unreachableURL;
515 };
516
queueLoadHTMLString(const CppArgumentList & arguments,CppVariant * result)517 void LayoutTestController::queueLoadHTMLString(const CppArgumentList& arguments, CppVariant* result)
518 {
519 if (arguments.size() > 0 && arguments[0].isString()) {
520 string html = arguments[0].toString();
521 WebURL baseURL;
522 if (arguments.size() > 1 && arguments[1].isString())
523 baseURL = WebURL(GURL(arguments[1].toString()));
524 if (arguments.size() > 2 && arguments[2].isString())
525 m_workQueue.addWork(new WorkItemLoadHTMLString(html, baseURL, WebURL(GURL(arguments[2].toString()))));
526 else
527 m_workQueue.addWork(new WorkItemLoadHTMLString(html, baseURL));
528 }
529 result->setNull();
530 }
531
objCIdentityIsEqual(const CppArgumentList & arguments,CppVariant * result)532 void LayoutTestController::objCIdentityIsEqual(const CppArgumentList& arguments, CppVariant* result)
533 {
534 if (arguments.size() < 2) {
535 // This is the best we can do to return an error.
536 result->setNull();
537 return;
538 }
539 result->set(arguments[0].isEqual(arguments[1]));
540 }
541
reset()542 void LayoutTestController::reset()
543 {
544 if (m_shell) {
545 m_shell->webView()->setZoomLevel(false, 0);
546 m_shell->webView()->setTabKeyCyclesThroughElements(true);
547 #if !OS(DARWIN) && !OS(WINDOWS) // Actually, TOOLKIT_GTK
548 // (Constants copied because we can't depend on the header that defined
549 // them from this file.)
550 m_shell->webView()->setSelectionColors(0xff1e90ff, 0xff000000, 0xffc8c8c8, 0xff323232);
551 #endif
552 m_shell->webView()->removeAllUserContent();
553 }
554 m_dumpAsText = false;
555 m_dumpEditingCallbacks = false;
556 m_dumpFrameLoadCallbacks = false;
557 m_dumpUserGestureInFrameLoadCallbacks = false;
558 m_dumpResourceLoadCallbacks = false;
559 m_dumpResourceResponseMIMETypes = false;
560 m_dumpBackForwardList = false;
561 m_dumpChildFrameScrollPositions = false;
562 m_dumpChildFramesAsText = false;
563 m_dumpWindowStatusChanges = false;
564 m_dumpSelectionRect = false;
565 m_dumpTitleChanges = false;
566 m_generatePixelResults = true;
567 m_acceptsEditing = true;
568 m_waitUntilDone = false;
569 m_canOpenWindows = false;
570 m_testRepaint = false;
571 m_sweepHorizontally = false;
572 m_shouldAddFileToPasteboard = false;
573 m_stopProvisionalFrameLoads = false;
574 m_deferMainResourceDataLoad = true;
575 m_globalFlag.set(false);
576 m_webHistoryItemCount.set(0);
577 m_titleTextDirection.set("ltr");
578 m_userStyleSheetLocation = WebURL();
579
580 webkit_support::SetAcceptAllCookies(false);
581 WebSecurityPolicy::resetOriginAccessWhitelists();
582
583 // Reset the default quota for each origin to 5MB
584 webkit_support::SetDatabaseQuota(5 * 1024 * 1024);
585
586 setlocale(LC_ALL, "");
587
588 if (m_closeRemainingWindows)
589 m_shell->closeRemainingWindows();
590 else
591 m_closeRemainingWindows = true;
592 m_workQueue.reset();
593 m_taskList.revokeAll();
594 }
595
locationChangeDone()596 void LayoutTestController::locationChangeDone()
597 {
598 m_webHistoryItemCount.set(m_shell->navigationEntryCount());
599
600 // No more new work after the first complete load.
601 m_workQueue.setFrozen(true);
602
603 if (!m_waitUntilDone)
604 m_workQueue.processWorkSoon();
605 }
606
policyDelegateDone()607 void LayoutTestController::policyDelegateDone()
608 {
609 ASSERT(m_waitUntilDone);
610 m_shell->testFinished();
611 m_waitUntilDone = false;
612 }
613
setCanOpenWindows(const CppArgumentList &,CppVariant * result)614 void LayoutTestController::setCanOpenWindows(const CppArgumentList&, CppVariant* result)
615 {
616 m_canOpenWindows = true;
617 result->setNull();
618 }
619
setTabKeyCyclesThroughElements(const CppArgumentList & arguments,CppVariant * result)620 void LayoutTestController::setTabKeyCyclesThroughElements(const CppArgumentList& arguments, CppVariant* result)
621 {
622 if (arguments.size() > 0 && arguments[0].isBool())
623 m_shell->webView()->setTabKeyCyclesThroughElements(arguments[0].toBoolean());
624 result->setNull();
625 }
626
windowCount(const CppArgumentList &,CppVariant * result)627 void LayoutTestController::windowCount(const CppArgumentList&, CppVariant* result)
628 {
629 result->set(static_cast<int>(m_shell->windowCount()));
630 }
631
setCloseRemainingWindowsWhenComplete(const CppArgumentList & arguments,CppVariant * result)632 void LayoutTestController::setCloseRemainingWindowsWhenComplete(const CppArgumentList& arguments, CppVariant* result)
633 {
634 if (arguments.size() > 0 && arguments[0].isBool())
635 m_closeRemainingWindows = arguments[0].value.boolValue;
636 result->setNull();
637 }
638
setAlwaysAcceptCookies(const CppArgumentList & arguments,CppVariant * result)639 void LayoutTestController::setAlwaysAcceptCookies(const CppArgumentList& arguments, CppVariant* result)
640 {
641 if (arguments.size() > 0)
642 webkit_support::SetAcceptAllCookies(cppVariantToBool(arguments[0]));
643 result->setNull();
644 }
645
setAsynchronousSpellCheckingEnabled(const CppArgumentList & arguments,CppVariant * result)646 void LayoutTestController::setAsynchronousSpellCheckingEnabled(const CppArgumentList& arguments, CppVariant* result)
647 {
648 if (arguments.size() > 0 && arguments[0].isBool())
649 m_shell->webView()->settings()->setAsynchronousSpellCheckingEnabled(cppVariantToBool(arguments[0]));
650 result->setNull();
651 }
652
shadowRoot(const CppArgumentList & arguments,CppVariant * result)653 void LayoutTestController::shadowRoot(const CppArgumentList& arguments, CppVariant* result)
654 {
655 if (arguments.size() != 1 || !arguments[0].isObject()) {
656 result->setNull();
657 return;
658 }
659
660 WebElement element;
661 if (!WebBindings::getElement(arguments[0].value.objectValue, &element)) {
662 result->setNull();
663 return;
664 }
665
666 WebNode shadowRoot = element.shadowRoot();
667 if (shadowRoot.isNull()) {
668 result->setNull();
669 return;
670 }
671
672 result->set(WebBindings::makeNode(shadowRoot));
673 }
674
showWebInspector(const CppArgumentList &,CppVariant * result)675 void LayoutTestController::showWebInspector(const CppArgumentList&, CppVariant* result)
676 {
677 m_shell->showDevTools();
678 result->setNull();
679 }
680
closeWebInspector(const CppArgumentList & args,CppVariant * result)681 void LayoutTestController::closeWebInspector(const CppArgumentList& args, CppVariant* result)
682 {
683 m_shell->closeDevTools();
684 result->setNull();
685 }
686
setWindowIsKey(const CppArgumentList & arguments,CppVariant * result)687 void LayoutTestController::setWindowIsKey(const CppArgumentList& arguments, CppVariant* result)
688 {
689 if (arguments.size() > 0 && arguments[0].isBool())
690 m_shell->setFocus(m_shell->webView(), arguments[0].value.boolValue);
691 result->setNull();
692 }
693
setUserStyleSheetEnabled(const CppArgumentList & arguments,CppVariant * result)694 void LayoutTestController::setUserStyleSheetEnabled(const CppArgumentList& arguments, CppVariant* result)
695 {
696 if (arguments.size() > 0 && arguments[0].isBool()) {
697 m_shell->preferences()->userStyleSheetLocation = arguments[0].value.boolValue ? m_userStyleSheetLocation : WebURL();
698 m_shell->applyPreferences();
699 }
700 result->setNull();
701 }
702
setUserStyleSheetLocation(const CppArgumentList & arguments,CppVariant * result)703 void LayoutTestController::setUserStyleSheetLocation(const CppArgumentList& arguments, CppVariant* result)
704 {
705 if (arguments.size() > 0 && arguments[0].isString()) {
706 m_userStyleSheetLocation = webkit_support::LocalFileToDataURL(
707 webkit_support::RewriteLayoutTestsURL(arguments[0].toString()));
708 m_shell->preferences()->userStyleSheetLocation = m_userStyleSheetLocation;
709 m_shell->applyPreferences();
710 }
711 result->setNull();
712 }
713
setAuthorAndUserStylesEnabled(const CppArgumentList & arguments,CppVariant * result)714 void LayoutTestController::setAuthorAndUserStylesEnabled(const CppArgumentList& arguments, CppVariant* result)
715 {
716 if (arguments.size() > 0 && arguments[0].isBool()) {
717 m_shell->preferences()->authorAndUserStylesEnabled = arguments[0].value.boolValue;
718 m_shell->applyPreferences();
719 }
720 result->setNull();
721 }
722
execCommand(const CppArgumentList & arguments,CppVariant * result)723 void LayoutTestController::execCommand(const CppArgumentList& arguments, CppVariant* result)
724 {
725 result->setNull();
726 if (arguments.size() <= 0 || !arguments[0].isString())
727 return;
728
729 std::string command = arguments[0].toString();
730 std::string value("");
731 // Ignore the second parameter (which is userInterface)
732 // since this command emulates a manual action.
733 if (arguments.size() >= 3 && arguments[2].isString())
734 value = arguments[2].toString();
735
736 // Note: webkit's version does not return the boolean, so neither do we.
737 m_shell->webView()->focusedFrame()->executeCommand(WebString::fromUTF8(command), WebString::fromUTF8(value));
738 }
739
isCommandEnabled(const CppArgumentList & arguments,CppVariant * result)740 void LayoutTestController::isCommandEnabled(const CppArgumentList& arguments, CppVariant* result)
741 {
742 if (arguments.size() <= 0 || !arguments[0].isString()) {
743 result->setNull();
744 return;
745 }
746
747 std::string command = arguments[0].toString();
748 bool rv = m_shell->webView()->focusedFrame()->isCommandEnabled(WebString::fromUTF8(command));
749 result->set(rv);
750 }
751
setPopupBlockingEnabled(const CppArgumentList & arguments,CppVariant * result)752 void LayoutTestController::setPopupBlockingEnabled(const CppArgumentList& arguments, CppVariant* result)
753 {
754 if (arguments.size() > 0 && arguments[0].isBool()) {
755 bool blockPopups = arguments[0].toBoolean();
756 m_shell->preferences()->javaScriptCanOpenWindowsAutomatically = !blockPopups;
757 m_shell->applyPreferences();
758 }
759 result->setNull();
760 }
761
setUseDashboardCompatibilityMode(const CppArgumentList &,CppVariant * result)762 void LayoutTestController::setUseDashboardCompatibilityMode(const CppArgumentList&, CppVariant* result)
763 {
764 // We have no need to support Dashboard Compatibility Mode (mac-only)
765 result->setNull();
766 }
767
clearAllApplicationCaches(const CppArgumentList &,CppVariant * result)768 void LayoutTestController::clearAllApplicationCaches(const CppArgumentList&, CppVariant* result)
769 {
770 // FIXME: Implement to support application cache quotas.
771 result->setNull();
772 }
773
clearApplicationCacheForOrigin(const CppArgumentList &,CppVariant * result)774 void LayoutTestController::clearApplicationCacheForOrigin(const CppArgumentList&, CppVariant* result)
775 {
776 // FIXME: Implement to support deleting all application cache for an origin.
777 result->setNull();
778 }
779
setApplicationCacheOriginQuota(const CppArgumentList &,CppVariant * result)780 void LayoutTestController::setApplicationCacheOriginQuota(const CppArgumentList&, CppVariant* result)
781 {
782 // FIXME: Implement to support application cache quotas.
783 result->setNull();
784 }
785
originsWithApplicationCache(const CppArgumentList &,CppVariant * result)786 void LayoutTestController::originsWithApplicationCache(const CppArgumentList&, CppVariant* result)
787 {
788 // FIXME: Implement to support getting origins that have application caches.
789 result->setNull();
790 }
791
setScrollbarPolicy(const CppArgumentList &,CppVariant * result)792 void LayoutTestController::setScrollbarPolicy(const CppArgumentList&, CppVariant* result)
793 {
794 // FIXME: implement.
795 // Currently only has a non-null implementation on QT.
796 result->setNull();
797 }
798
setCustomPolicyDelegate(const CppArgumentList & arguments,CppVariant * result)799 void LayoutTestController::setCustomPolicyDelegate(const CppArgumentList& arguments, CppVariant* result)
800 {
801 if (arguments.size() > 0 && arguments[0].isBool()) {
802 bool enable = arguments[0].value.boolValue;
803 bool permissive = false;
804 if (arguments.size() > 1 && arguments[1].isBool())
805 permissive = arguments[1].value.boolValue;
806 m_shell->webViewHost()->setCustomPolicyDelegate(enable, permissive);
807 }
808 result->setNull();
809 }
810
waitForPolicyDelegate(const CppArgumentList &,CppVariant * result)811 void LayoutTestController::waitForPolicyDelegate(const CppArgumentList&, CppVariant* result)
812 {
813 m_shell->webViewHost()->waitForPolicyDelegate();
814 m_waitUntilDone = true;
815 result->setNull();
816 }
817
setWillSendRequestClearHeader(const CppArgumentList & arguments,CppVariant * result)818 void LayoutTestController::setWillSendRequestClearHeader(const CppArgumentList& arguments, CppVariant* result)
819 {
820 if (arguments.size() > 0 && arguments[0].isString()) {
821 string header = arguments[0].toString();
822 if (!header.empty())
823 m_shell->webViewHost()->addClearHeader(String::fromUTF8(header.c_str()));
824 }
825 result->setNull();
826 }
827
setWillSendRequestReturnsNullOnRedirect(const CppArgumentList & arguments,CppVariant * result)828 void LayoutTestController::setWillSendRequestReturnsNullOnRedirect(const CppArgumentList& arguments, CppVariant* result)
829 {
830 if (arguments.size() > 0 && arguments[0].isBool())
831 m_shell->webViewHost()->setBlockRedirects(arguments[0].value.boolValue);
832 result->setNull();
833 }
834
setWillSendRequestReturnsNull(const CppArgumentList & arguments,CppVariant * result)835 void LayoutTestController::setWillSendRequestReturnsNull(const CppArgumentList& arguments, CppVariant* result)
836 {
837 if (arguments.size() > 0 && arguments[0].isBool())
838 m_shell->webViewHost()->setRequestReturnNull(arguments[0].value.boolValue);
839 result->setNull();
840 }
841
pathToLocalResource(const CppArgumentList & arguments,CppVariant * result)842 void LayoutTestController::pathToLocalResource(const CppArgumentList& arguments, CppVariant* result)
843 {
844 result->setNull();
845 if (arguments.size() <= 0 || !arguments[0].isString())
846 return;
847
848 string url = arguments[0].toString();
849 #if OS(WINDOWS)
850 if (!url.find("/tmp/")) {
851 // We want a temp file.
852 const unsigned tempPrefixLength = 5;
853 size_t bufferSize = MAX_PATH;
854 OwnArrayPtr<WCHAR> tempPath = adoptArrayPtr(new WCHAR[bufferSize]);
855 DWORD tempLength = ::GetTempPathW(bufferSize, tempPath.get());
856 if (tempLength + url.length() - tempPrefixLength + 1 > bufferSize) {
857 bufferSize = tempLength + url.length() - tempPrefixLength + 1;
858 tempPath = adoptArrayPtr(new WCHAR[bufferSize]);
859 tempLength = GetTempPathW(bufferSize, tempPath.get());
860 ASSERT(tempLength < bufferSize);
861 }
862 string resultPath(WebString(tempPath.get(), tempLength).utf8());
863 resultPath.append(url.substr(tempPrefixLength));
864 result->set(resultPath);
865 return;
866 }
867 #endif
868
869 // Some layout tests use file://// which we resolve as a UNC path. Normalize
870 // them to just file:///.
871 string lowerUrl = url;
872 transform(lowerUrl.begin(), lowerUrl.end(), lowerUrl.begin(), ::tolower);
873 while (!lowerUrl.find("file:////")) {
874 url = url.substr(0, 8) + url.substr(9);
875 lowerUrl = lowerUrl.substr(0, 8) + lowerUrl.substr(9);
876 }
877 result->set(webkit_support::RewriteLayoutTestsURL(url).spec());
878 }
879
addFileToPasteboardOnDrag(const CppArgumentList &,CppVariant * result)880 void LayoutTestController::addFileToPasteboardOnDrag(const CppArgumentList&, CppVariant* result)
881 {
882 result->setNull();
883 m_shouldAddFileToPasteboard = true;
884 }
885
setStopProvisionalFrameLoads(const CppArgumentList &,CppVariant * result)886 void LayoutTestController::setStopProvisionalFrameLoads(const CppArgumentList&, CppVariant* result)
887 {
888 result->setNull();
889 m_stopProvisionalFrameLoads = true;
890 }
891
setSmartInsertDeleteEnabled(const CppArgumentList & arguments,CppVariant * result)892 void LayoutTestController::setSmartInsertDeleteEnabled(const CppArgumentList& arguments, CppVariant* result)
893 {
894 if (arguments.size() > 0 && arguments[0].isBool())
895 m_shell->webViewHost()->setSmartInsertDeleteEnabled(arguments[0].value.boolValue);
896 result->setNull();
897 }
898
setSelectTrailingWhitespaceEnabled(const CppArgumentList & arguments,CppVariant * result)899 void LayoutTestController::setSelectTrailingWhitespaceEnabled(const CppArgumentList& arguments, CppVariant* result)
900 {
901 if (arguments.size() > 0 && arguments[0].isBool())
902 m_shell->webViewHost()->setSelectTrailingWhitespaceEnabled(arguments[0].value.boolValue);
903 result->setNull();
904 }
905
pauseAnimationAtTimeOnElementWithId(const WebString & animationName,double time,const WebString & elementId)906 bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(const WebString& animationName, double time, const WebString& elementId)
907 {
908 WebFrame* webFrame = m_shell->webView()->mainFrame();
909 if (!webFrame)
910 return false;
911
912 WebAnimationController* controller = webFrame->animationController();
913 if (!controller)
914 return false;
915
916 WebElement element = webFrame->document().getElementById(elementId);
917 if (element.isNull())
918 return false;
919 return controller->pauseAnimationAtTime(element, animationName, time);
920 }
921
pauseTransitionAtTimeOnElementWithId(const WebString & propertyName,double time,const WebString & elementId)922 bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(const WebString& propertyName, double time, const WebString& elementId)
923 {
924 WebFrame* webFrame = m_shell->webView()->mainFrame();
925 if (!webFrame)
926 return false;
927
928 WebAnimationController* controller = webFrame->animationController();
929 if (!controller)
930 return false;
931
932 WebElement element = webFrame->document().getElementById(elementId);
933 if (element.isNull())
934 return false;
935 return controller->pauseTransitionAtTime(element, propertyName, time);
936 }
937
elementDoesAutoCompleteForElementWithId(const WebString & elementId)938 bool LayoutTestController::elementDoesAutoCompleteForElementWithId(const WebString& elementId)
939 {
940 WebFrame* webFrame = m_shell->webView()->mainFrame();
941 if (!webFrame)
942 return false;
943
944 WebElement element = webFrame->document().getElementById(elementId);
945 if (element.isNull() || !element.hasTagName("input"))
946 return false;
947
948 WebInputElement inputElement = element.to<WebInputElement>();
949 return inputElement.autoComplete();
950 }
951
numberOfActiveAnimations()952 int LayoutTestController::numberOfActiveAnimations()
953 {
954 WebFrame* webFrame = m_shell->webView()->mainFrame();
955 if (!webFrame)
956 return -1;
957
958 WebAnimationController* controller = webFrame->animationController();
959 if (!controller)
960 return -1;
961
962 return controller->numberOfActiveAnimations();
963 }
964
suspendAnimations()965 void LayoutTestController::suspendAnimations()
966 {
967 WebFrame* webFrame = m_shell->webView()->mainFrame();
968 if (!webFrame)
969 return;
970
971 WebAnimationController* controller = webFrame->animationController();
972 if (!controller)
973 return;
974
975 controller->suspendAnimations();
976 }
977
resumeAnimations()978 void LayoutTestController::resumeAnimations()
979 {
980 WebFrame* webFrame = m_shell->webView()->mainFrame();
981 if (!webFrame)
982 return;
983
984 WebAnimationController* controller = webFrame->animationController();
985 if (!controller)
986 return;
987
988 controller->resumeAnimations();
989 }
990
pauseAnimationAtTimeOnElementWithId(const CppArgumentList & arguments,CppVariant * result)991 void LayoutTestController::pauseAnimationAtTimeOnElementWithId(const CppArgumentList& arguments, CppVariant* result)
992 {
993 result->set(false);
994 if (arguments.size() > 2 && arguments[0].isString() && arguments[1].isNumber() && arguments[2].isString()) {
995 WebString animationName = cppVariantToWebString(arguments[0]);
996 double time = arguments[1].toDouble();
997 WebString elementId = cppVariantToWebString(arguments[2]);
998 result->set(pauseAnimationAtTimeOnElementWithId(animationName, time, elementId));
999 }
1000 }
1001
pauseTransitionAtTimeOnElementWithId(const CppArgumentList & arguments,CppVariant * result)1002 void LayoutTestController::pauseTransitionAtTimeOnElementWithId(const CppArgumentList& arguments, CppVariant* result)
1003 {
1004 result->set(false);
1005 if (arguments.size() > 2 && arguments[0].isString() && arguments[1].isNumber() && arguments[2].isString()) {
1006 WebString propertyName = cppVariantToWebString(arguments[0]);
1007 double time = arguments[1].toDouble();
1008 WebString elementId = cppVariantToWebString(arguments[2]);
1009 result->set(pauseTransitionAtTimeOnElementWithId(propertyName, time, elementId));
1010 }
1011 }
1012
elementDoesAutoCompleteForElementWithId(const CppArgumentList & arguments,CppVariant * result)1013 void LayoutTestController::elementDoesAutoCompleteForElementWithId(const CppArgumentList& arguments, CppVariant* result)
1014 {
1015 if (arguments.size() != 1 || !arguments[0].isString()) {
1016 result->set(false);
1017 return;
1018 }
1019 WebString elementId = cppVariantToWebString(arguments[0]);
1020 result->set(elementDoesAutoCompleteForElementWithId(elementId));
1021 }
1022
numberOfActiveAnimations(const CppArgumentList &,CppVariant * result)1023 void LayoutTestController::numberOfActiveAnimations(const CppArgumentList&, CppVariant* result)
1024 {
1025 result->set(numberOfActiveAnimations());
1026 }
1027
suspendAnimations(const CppArgumentList &,CppVariant * result)1028 void LayoutTestController::suspendAnimations(const CppArgumentList&, CppVariant* result)
1029 {
1030 suspendAnimations();
1031 result->setNull();
1032 }
1033
resumeAnimations(const CppArgumentList &,CppVariant * result)1034 void LayoutTestController::resumeAnimations(const CppArgumentList&, CppVariant* result)
1035 {
1036 resumeAnimations();
1037 result->setNull();
1038 }
1039
sampleSVGAnimationForElementAtTime(const CppArgumentList & arguments,CppVariant * result)1040 void LayoutTestController::sampleSVGAnimationForElementAtTime(const CppArgumentList& arguments, CppVariant* result)
1041 {
1042 if (arguments.size() != 3) {
1043 result->setNull();
1044 return;
1045 }
1046 WebString animationId = cppVariantToWebString(arguments[0]);
1047 double time = arguments[1].toDouble();
1048 WebString elementId = cppVariantToWebString(arguments[2]);
1049 bool success = m_shell->webView()->mainFrame()->pauseSVGAnimation(animationId, time, elementId);
1050 result->set(success);
1051 }
1052
disableImageLoading(const CppArgumentList &,CppVariant * result)1053 void LayoutTestController::disableImageLoading(const CppArgumentList&, CppVariant* result)
1054 {
1055 m_shell->preferences()->loadsImagesAutomatically = false;
1056 m_shell->applyPreferences();
1057 result->setNull();
1058 }
1059
setIconDatabaseEnabled(const CppArgumentList &,CppVariant * result)1060 void LayoutTestController::setIconDatabaseEnabled(const CppArgumentList&, CppVariant* result)
1061 {
1062 // We don't use the WebKit icon database.
1063 result->setNull();
1064 }
1065
callShouldCloseOnWebView(const CppArgumentList &,CppVariant * result)1066 void LayoutTestController::callShouldCloseOnWebView(const CppArgumentList&, CppVariant* result)
1067 {
1068 result->set(m_shell->webView()->dispatchBeforeUnloadEvent());
1069 }
1070
grantDesktopNotificationPermission(const CppArgumentList & arguments,CppVariant * result)1071 void LayoutTestController::grantDesktopNotificationPermission(const CppArgumentList& arguments, CppVariant* result)
1072 {
1073 if (arguments.size() != 1 || !arguments[0].isString()) {
1074 result->set(false);
1075 return;
1076 }
1077 m_shell->notificationPresenter()->grantPermission(cppVariantToWebString(arguments[0]));
1078 result->set(true);
1079 }
1080
simulateDesktopNotificationClick(const CppArgumentList & arguments,CppVariant * result)1081 void LayoutTestController::simulateDesktopNotificationClick(const CppArgumentList& arguments, CppVariant* result)
1082 {
1083 if (arguments.size() != 1 || !arguments[0].isString()) {
1084 result->set(false);
1085 return;
1086 }
1087 if (m_shell->notificationPresenter()->simulateClick(cppVariantToWebString(arguments[0])))
1088 result->set(true);
1089 else
1090 result->set(false);
1091 }
1092
setDomainRelaxationForbiddenForURLScheme(const CppArgumentList & arguments,CppVariant * result)1093 void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(const CppArgumentList& arguments, CppVariant* result)
1094 {
1095 if (arguments.size() != 2 || !arguments[0].isBool() || !arguments[1].isString())
1096 return;
1097 m_shell->webView()->setDomainRelaxationForbidden(cppVariantToBool(arguments[0]), cppVariantToWebString(arguments[1]));
1098 }
1099
setDeferMainResourceDataLoad(const CppArgumentList & arguments,CppVariant * result)1100 void LayoutTestController::setDeferMainResourceDataLoad(const CppArgumentList& arguments, CppVariant* result)
1101 {
1102 if (arguments.size() == 1)
1103 m_deferMainResourceDataLoad = cppVariantToBool(arguments[0]);
1104 }
1105
1106 //
1107 // Unimplemented stubs
1108 //
1109
dumpAsWebArchive(const CppArgumentList & arguments,CppVariant * result)1110 void LayoutTestController::dumpAsWebArchive(const CppArgumentList& arguments, CppVariant* result)
1111 {
1112 result->setNull();
1113 }
1114
setMainFrameIsFirstResponder(const CppArgumentList & arguments,CppVariant * result)1115 void LayoutTestController::setMainFrameIsFirstResponder(const CppArgumentList& arguments, CppVariant* result)
1116 {
1117 result->setNull();
1118 }
1119
dumpSelectionRect(const CppArgumentList & arguments,CppVariant * result)1120 void LayoutTestController::dumpSelectionRect(const CppArgumentList& arguments, CppVariant* result)
1121 {
1122 m_dumpSelectionRect = true;
1123 result->setNull();
1124 }
1125
display(const CppArgumentList & arguments,CppVariant * result)1126 void LayoutTestController::display(const CppArgumentList& arguments, CppVariant* result)
1127 {
1128 WebViewHost* host = m_shell->webViewHost();
1129 const WebKit::WebSize& size = m_shell->webView()->size();
1130 WebRect rect(0, 0, size.width, size.height);
1131 host->updatePaintRect(rect);
1132 host->paintInvalidatedRegion();
1133 host->displayRepaintMask();
1134 result->setNull();
1135 }
1136
displayInvalidatedRegion(const CppArgumentList & arguments,CppVariant * result)1137 void LayoutTestController::displayInvalidatedRegion(const CppArgumentList& arguments, CppVariant* result)
1138 {
1139 WebViewHost* host = m_shell->webViewHost();
1140 host->paintInvalidatedRegion();
1141 host->displayRepaintMask();
1142 result->setNull();
1143 }
1144
testRepaint(const CppArgumentList &,CppVariant * result)1145 void LayoutTestController::testRepaint(const CppArgumentList&, CppVariant* result)
1146 {
1147 m_testRepaint = true;
1148 result->setNull();
1149 }
1150
repaintSweepHorizontally(const CppArgumentList &,CppVariant * result)1151 void LayoutTestController::repaintSweepHorizontally(const CppArgumentList&, CppVariant* result)
1152 {
1153 m_sweepHorizontally = true;
1154 result->setNull();
1155 }
1156
clearBackForwardList(const CppArgumentList & arguments,CppVariant * result)1157 void LayoutTestController::clearBackForwardList(const CppArgumentList& arguments, CppVariant* result)
1158 {
1159 result->setNull();
1160 }
1161
keepWebHistory(const CppArgumentList & arguments,CppVariant * result)1162 void LayoutTestController::keepWebHistory(const CppArgumentList& arguments, CppVariant* result)
1163 {
1164 result->setNull();
1165 }
1166
storeWebScriptObject(const CppArgumentList & arguments,CppVariant * result)1167 void LayoutTestController::storeWebScriptObject(const CppArgumentList& arguments, CppVariant* result)
1168 {
1169 result->setNull();
1170 }
1171
accessStoredWebScriptObject(const CppArgumentList & arguments,CppVariant * result)1172 void LayoutTestController::accessStoredWebScriptObject(const CppArgumentList& arguments, CppVariant* result)
1173 {
1174 result->setNull();
1175 }
1176
objCClassNameOf(const CppArgumentList & arguments,CppVariant * result)1177 void LayoutTestController::objCClassNameOf(const CppArgumentList& arguments, CppVariant* result)
1178 {
1179 result->setNull();
1180 }
1181
addDisallowedURL(const CppArgumentList & arguments,CppVariant * result)1182 void LayoutTestController::addDisallowedURL(const CppArgumentList& arguments, CppVariant* result)
1183 {
1184 result->setNull();
1185 }
1186
setCallCloseOnWebViews(const CppArgumentList & arguments,CppVariant * result)1187 void LayoutTestController::setCallCloseOnWebViews(const CppArgumentList& arguments, CppVariant* result)
1188 {
1189 result->setNull();
1190 }
1191
setPrivateBrowsingEnabled(const CppArgumentList & arguments,CppVariant * result)1192 void LayoutTestController::setPrivateBrowsingEnabled(const CppArgumentList& arguments, CppVariant* result)
1193 {
1194 result->setNull();
1195 }
1196
setJavaScriptCanAccessClipboard(const CppArgumentList & arguments,CppVariant * result)1197 void LayoutTestController::setJavaScriptCanAccessClipboard(const CppArgumentList& arguments, CppVariant* result)
1198 {
1199 if (arguments.size() > 0 && arguments[0].isBool()) {
1200 m_shell->preferences()->javaScriptCanAccessClipboard = arguments[0].value.boolValue;
1201 m_shell->applyPreferences();
1202 }
1203 result->setNull();
1204 }
1205
setXSSAuditorEnabled(const CppArgumentList & arguments,CppVariant * result)1206 void LayoutTestController::setXSSAuditorEnabled(const CppArgumentList& arguments, CppVariant* result)
1207 {
1208 if (arguments.size() > 0 && arguments[0].isBool()) {
1209 m_shell->preferences()->XSSAuditorEnabled = arguments[0].value.boolValue;
1210 m_shell->applyPreferences();
1211 }
1212 result->setNull();
1213 }
1214
evaluateScriptInIsolatedWorld(const CppArgumentList & arguments,CppVariant * result)1215 void LayoutTestController::evaluateScriptInIsolatedWorld(const CppArgumentList& arguments, CppVariant* result)
1216 {
1217 if (arguments.size() >= 2 && arguments[0].isNumber() && arguments[1].isString()) {
1218 WebScriptSource source(cppVariantToWebString(arguments[1]));
1219 // This relies on the iframe focusing itself when it loads. This is a bit
1220 // sketchy, but it seems to be what other tests do.
1221 m_shell->webView()->focusedFrame()->executeScriptInIsolatedWorld(arguments[0].toInt32(), &source, 1, 1);
1222 }
1223 result->setNull();
1224 }
1225
setAllowUniversalAccessFromFileURLs(const CppArgumentList & arguments,CppVariant * result)1226 void LayoutTestController::setAllowUniversalAccessFromFileURLs(const CppArgumentList& arguments, CppVariant* result)
1227 {
1228 if (arguments.size() > 0 && arguments[0].isBool()) {
1229 m_shell->preferences()->allowUniversalAccessFromFileURLs = arguments[0].value.boolValue;
1230 m_shell->applyPreferences();
1231 }
1232 result->setNull();
1233 }
1234
setAllowFileAccessFromFileURLs(const CppArgumentList & arguments,CppVariant * result)1235 void LayoutTestController::setAllowFileAccessFromFileURLs(const CppArgumentList& arguments, CppVariant* result)
1236 {
1237 if (arguments.size() > 0 && arguments[0].isBool()) {
1238 m_shell->preferences()->allowFileAccessFromFileURLs = arguments[0].value.boolValue;
1239 m_shell->applyPreferences();
1240 }
1241 result->setNull();
1242 }
1243
1244 // Need these conversions because the format of the value for booleans
1245 // may vary - for example, on mac "1" and "0" are used for boolean.
cppVariantToBool(const CppVariant & value)1246 bool LayoutTestController::cppVariantToBool(const CppVariant& value)
1247 {
1248 if (value.isBool())
1249 return value.toBoolean();
1250 if (value.isNumber())
1251 return value.toInt32();
1252 if (value.isString()) {
1253 string valueString = value.toString();
1254 if (valueString == "true" || valueString == "1")
1255 return true;
1256 if (valueString == "false" || valueString == "0")
1257 return false;
1258 }
1259 logErrorToConsole("Invalid value. Expected boolean value.");
1260 return false;
1261 }
1262
cppVariantToInt32(const CppVariant & value)1263 int32_t LayoutTestController::cppVariantToInt32(const CppVariant& value)
1264 {
1265 if (value.isNumber())
1266 return value.toInt32();
1267 if (value.isString()) {
1268 string stringSource = value.toString();
1269 const char* source = stringSource.data();
1270 char* end;
1271 long number = strtol(source, &end, 10);
1272 if (end == source + stringSource.length() && number >= numeric_limits<int32_t>::min() && number <= numeric_limits<int32_t>::max())
1273 return static_cast<int32_t>(number);
1274 }
1275 logErrorToConsole("Invalid value for preference. Expected integer value.");
1276 return 0;
1277 }
1278
cppVariantToWebString(const CppVariant & value)1279 WebString LayoutTestController::cppVariantToWebString(const CppVariant& value)
1280 {
1281 if (!value.isString()) {
1282 logErrorToConsole("Invalid value for preference. Expected string value.");
1283 return WebString();
1284 }
1285 return WebString::fromUTF8(value.toString());
1286 }
1287
overridePreference(const CppArgumentList & arguments,CppVariant * result)1288 void LayoutTestController::overridePreference(const CppArgumentList& arguments, CppVariant* result)
1289 {
1290 result->setNull();
1291 if (arguments.size() != 2 || !arguments[0].isString())
1292 return;
1293
1294 string key = arguments[0].toString();
1295 CppVariant value = arguments[1];
1296 WebPreferences* prefs = m_shell->preferences();
1297 if (key == "WebKitStandardFont")
1298 prefs->standardFontFamily = cppVariantToWebString(value);
1299 else if (key == "WebKitFixedFont")
1300 prefs->fixedFontFamily = cppVariantToWebString(value);
1301 else if (key == "WebKitSerifFont")
1302 prefs->serifFontFamily = cppVariantToWebString(value);
1303 else if (key == "WebKitSansSerifFont")
1304 prefs->sansSerifFontFamily = cppVariantToWebString(value);
1305 else if (key == "WebKitCursiveFont")
1306 prefs->cursiveFontFamily = cppVariantToWebString(value);
1307 else if (key == "WebKitFantasyFont")
1308 prefs->fantasyFontFamily = cppVariantToWebString(value);
1309 else if (key == "WebKitDefaultFontSize")
1310 prefs->defaultFontSize = cppVariantToInt32(value);
1311 else if (key == "WebKitDefaultFixedFontSize")
1312 prefs->defaultFixedFontSize = cppVariantToInt32(value);
1313 else if (key == "WebKitMinimumFontSize")
1314 prefs->minimumFontSize = cppVariantToInt32(value);
1315 else if (key == "WebKitMinimumLogicalFontSize")
1316 prefs->minimumLogicalFontSize = cppVariantToInt32(value);
1317 else if (key == "WebKitDefaultTextEncodingName")
1318 prefs->defaultTextEncodingName = cppVariantToWebString(value);
1319 else if (key == "WebKitJavaScriptEnabled")
1320 prefs->javaScriptEnabled = cppVariantToBool(value);
1321 else if (key == "WebKitWebSecurityEnabled")
1322 prefs->webSecurityEnabled = cppVariantToBool(value);
1323 else if (key == "WebKitJavaScriptCanOpenWindowsAutomatically")
1324 prefs->javaScriptCanOpenWindowsAutomatically = cppVariantToBool(value);
1325 else if (key == "WebKitDisplayImagesKey")
1326 prefs->loadsImagesAutomatically = cppVariantToBool(value);
1327 else if (key == "WebKitPluginsEnabled")
1328 prefs->pluginsEnabled = cppVariantToBool(value);
1329 else if (key == "WebKitDOMPasteAllowedPreferenceKey")
1330 prefs->DOMPasteAllowed = cppVariantToBool(value);
1331 else if (key == "WebKitDeveloperExtrasEnabledPreferenceKey")
1332 prefs->developerExtrasEnabled = cppVariantToBool(value);
1333 else if (key == "WebKitShrinksStandaloneImagesToFit")
1334 prefs->shrinksStandaloneImagesToFit = cppVariantToBool(value);
1335 else if (key == "WebKitTextAreasAreResizable")
1336 prefs->textAreasAreResizable = cppVariantToBool(value);
1337 else if (key == "WebKitJavaEnabled")
1338 prefs->javaEnabled = cppVariantToBool(value);
1339 else if (key == "WebKitUsesPageCachePreferenceKey")
1340 prefs->usesPageCache = cppVariantToBool(value);
1341 else if (key == "WebKitJavaScriptCanAccessClipboard")
1342 prefs->javaScriptCanAccessClipboard = cppVariantToBool(value);
1343 else if (key == "WebKitXSSAuditorEnabled")
1344 prefs->XSSAuditorEnabled = cppVariantToBool(value);
1345 else if (key == "WebKitLocalStorageEnabledPreferenceKey")
1346 prefs->localStorageEnabled = cppVariantToBool(value);
1347 else if (key == "WebKitOfflineWebApplicationCacheEnabled")
1348 prefs->offlineWebApplicationCacheEnabled = cppVariantToBool(value);
1349 else if (key == "WebKitTabToLinksPreferenceKey")
1350 prefs->tabsToLinks = cppVariantToBool(value);
1351 else if (key == "WebKitWebGLEnabled")
1352 prefs->experimentalWebGLEnabled = cppVariantToBool(value);
1353 else if (key == "WebKitHyperlinkAuditingEnabled")
1354 prefs->hyperlinkAuditingEnabled = cppVariantToBool(value);
1355 else if (key == "WebKitEnableCaretBrowsing")
1356 prefs->caretBrowsingEnabled = cppVariantToBool(value);
1357 else {
1358 string message("Invalid name for preference: ");
1359 message.append(key);
1360 logErrorToConsole(message);
1361 }
1362 m_shell->applyPreferences();
1363 }
1364
fallbackMethod(const CppArgumentList &,CppVariant * result)1365 void LayoutTestController::fallbackMethod(const CppArgumentList&, CppVariant* result)
1366 {
1367 printf("CONSOLE MESSAGE: JavaScript ERROR: unknown method called on LayoutTestController\n");
1368 result->setNull();
1369 }
1370
addOriginAccessWhitelistEntry(const CppArgumentList & arguments,CppVariant * result)1371 void LayoutTestController::addOriginAccessWhitelistEntry(const CppArgumentList& arguments, CppVariant* result)
1372 {
1373 result->setNull();
1374
1375 if (arguments.size() != 4 || !arguments[0].isString() || !arguments[1].isString()
1376 || !arguments[2].isString() || !arguments[3].isBool())
1377 return;
1378
1379 WebKit::WebURL url(GURL(arguments[0].toString()));
1380 if (!url.isValid())
1381 return;
1382
1383 WebSecurityPolicy::addOriginAccessWhitelistEntry(
1384 url,
1385 cppVariantToWebString(arguments[1]),
1386 cppVariantToWebString(arguments[2]),
1387 arguments[3].toBoolean());
1388 }
1389
removeOriginAccessWhitelistEntry(const CppArgumentList & arguments,CppVariant * result)1390 void LayoutTestController::removeOriginAccessWhitelistEntry(const CppArgumentList& arguments, CppVariant* result)
1391 {
1392 result->setNull();
1393
1394 if (arguments.size() != 4 || !arguments[0].isString() || !arguments[1].isString()
1395 || !arguments[2].isString() || !arguments[3].isBool())
1396 return;
1397
1398 WebKit::WebURL url(GURL(arguments[0].toString()));
1399 if (!url.isValid())
1400 return;
1401
1402 WebSecurityPolicy::removeOriginAccessWhitelistEntry(
1403 url,
1404 cppVariantToWebString(arguments[1]),
1405 cppVariantToWebString(arguments[2]),
1406 arguments[3].toBoolean());
1407 }
1408
clearAllDatabases(const CppArgumentList & arguments,CppVariant * result)1409 void LayoutTestController::clearAllDatabases(const CppArgumentList& arguments, CppVariant* result)
1410 {
1411 result->setNull();
1412 webkit_support::ClearAllDatabases();
1413 }
1414
setDatabaseQuota(const CppArgumentList & arguments,CppVariant * result)1415 void LayoutTestController::setDatabaseQuota(const CppArgumentList& arguments, CppVariant* result)
1416 {
1417 result->setNull();
1418 if ((arguments.size() >= 1) && arguments[0].isNumber())
1419 webkit_support::SetDatabaseQuota(arguments[0].toInt32());
1420 }
1421
setPOSIXLocale(const CppArgumentList & arguments,CppVariant * result)1422 void LayoutTestController::setPOSIXLocale(const CppArgumentList& arguments, CppVariant* result)
1423 {
1424 result->setNull();
1425 if (arguments.size() == 1 && arguments[0].isString())
1426 setlocale(LC_ALL, arguments[0].toString().c_str());
1427 }
1428
counterValueForElementById(const CppArgumentList & arguments,CppVariant * result)1429 void LayoutTestController::counterValueForElementById(const CppArgumentList& arguments, CppVariant* result)
1430 {
1431 result->setNull();
1432 if (arguments.size() < 1 || !arguments[0].isString())
1433 return;
1434 WebFrame* frame = m_shell->webView()->mainFrame();
1435 if (!frame)
1436 return;
1437 WebString counterValue = frame->counterValueForElementById(cppVariantToWebString(arguments[0]));
1438 if (counterValue.isNull())
1439 return;
1440 result->set(counterValue.utf8());
1441 }
1442
parsePageSizeParameters(const CppArgumentList & arguments,int argOffset,int * pageWidthInPixels,int * pageHeightInPixels)1443 static bool parsePageSizeParameters(const CppArgumentList& arguments,
1444 int argOffset,
1445 int* pageWidthInPixels,
1446 int* pageHeightInPixels)
1447 {
1448 // WebKit is using the window width/height of DumpRenderTree as the
1449 // default value of the page size.
1450 // FIXME: share these values with other ports.
1451 *pageWidthInPixels = 800;
1452 *pageHeightInPixels = 600;
1453 switch (arguments.size() - argOffset) {
1454 case 2:
1455 if (!arguments[argOffset].isNumber() || !arguments[1 + argOffset].isNumber())
1456 return false;
1457 *pageWidthInPixels = arguments[argOffset].toInt32();
1458 *pageHeightInPixels = arguments[1 + argOffset].toInt32();
1459 // fall through.
1460 case 0:
1461 break;
1462 default:
1463 return false;
1464 }
1465 return true;
1466 }
1467
pageNumberForElementById(const CppArgumentList & arguments,CppVariant * result)1468 void LayoutTestController::pageNumberForElementById(const CppArgumentList& arguments, CppVariant* result)
1469 {
1470 result->setNull();
1471 int pageWidthInPixels = 0;
1472 int pageHeightInPixels = 0;
1473 if (!parsePageSizeParameters(arguments, 1,
1474 &pageWidthInPixels, &pageHeightInPixels))
1475 return;
1476 if (!arguments[0].isString())
1477 return;
1478 WebFrame* frame = m_shell->webView()->mainFrame();
1479 if (!frame)
1480 return;
1481 result->set(frame->pageNumberForElementById(cppVariantToWebString(arguments[0]),
1482 static_cast<float>(pageWidthInPixels),
1483 static_cast<float>(pageHeightInPixels)));
1484 }
1485
numberOfPages(const CppArgumentList & arguments,CppVariant * result)1486 void LayoutTestController::numberOfPages(const CppArgumentList& arguments, CppVariant* result)
1487 {
1488 result->setNull();
1489 int pageWidthInPixels = 0;
1490 int pageHeightInPixels = 0;
1491 if (!parsePageSizeParameters(arguments, 0, &pageWidthInPixels, &pageHeightInPixels))
1492 return;
1493
1494 WebFrame* frame = m_shell->webView()->mainFrame();
1495 if (!frame)
1496 return;
1497 WebSize size(pageWidthInPixels, pageHeightInPixels);
1498 int numberOfPages = frame->printBegin(size);
1499 frame->printEnd();
1500 result->set(numberOfPages);
1501 }
1502
numberOfPendingGeolocationPermissionRequests(const CppArgumentList & arguments,CppVariant * result)1503 void LayoutTestController::numberOfPendingGeolocationPermissionRequests(const CppArgumentList& arguments, CppVariant* result)
1504 {
1505 result->setNull();
1506 Vector<WebViewHost*> windowList = m_shell->windowList();
1507 int numberOfRequests = 0;
1508 for (size_t i = 0; i < windowList.size(); i++)
1509 numberOfRequests += windowList[i]->geolocationClientMock()->numberOfPendingPermissionRequests();
1510 result->set(numberOfRequests);
1511 }
1512
logErrorToConsole(const std::string & text)1513 void LayoutTestController::logErrorToConsole(const std::string& text)
1514 {
1515 m_shell->webViewHost()->didAddMessageToConsole(
1516 WebConsoleMessage(WebConsoleMessage::LevelError, WebString::fromUTF8(text)),
1517 WebString(), 0);
1518 }
1519
setTimelineProfilingEnabled(const CppArgumentList & arguments,CppVariant * result)1520 void LayoutTestController::setTimelineProfilingEnabled(const CppArgumentList& arguments, CppVariant* result)
1521 {
1522 result->setNull();
1523 if (arguments.size() < 1 || !arguments[0].isBool())
1524 return;
1525 m_shell->drtDevToolsAgent()->setTimelineProfilingEnabled(arguments[0].toBoolean());
1526 }
1527
evaluateInWebInspector(const CppArgumentList & arguments,CppVariant * result)1528 void LayoutTestController::evaluateInWebInspector(const CppArgumentList& arguments, CppVariant* result)
1529 {
1530 result->setNull();
1531 if (arguments.size() < 2 || !arguments[0].isNumber() || !arguments[1].isString())
1532 return;
1533 m_shell->drtDevToolsAgent()->evaluateInWebInspector(arguments[0].toInt32(), arguments[1].toString());
1534 }
1535
addUserScript(const CppArgumentList & arguments,CppVariant * result)1536 void LayoutTestController::addUserScript(const CppArgumentList& arguments, CppVariant* result)
1537 {
1538 result->setNull();
1539 if (arguments.size() < 3 || !arguments[0].isString() || !arguments[1].isBool() || !arguments[2].isBool())
1540 return;
1541 WebView::addUserScript(
1542 cppVariantToWebString(arguments[0]), WebVector<WebString>(),
1543 arguments[1].toBoolean() ? WebView::UserScriptInjectAtDocumentStart : WebView::UserScriptInjectAtDocumentEnd,
1544 arguments[2].toBoolean() ? WebView::UserContentInjectInAllFrames : WebView::UserContentInjectInTopFrameOnly);
1545 }
1546
addUserStyleSheet(const CppArgumentList & arguments,CppVariant * result)1547 void LayoutTestController::addUserStyleSheet(const CppArgumentList& arguments, CppVariant* result)
1548 {
1549 result->setNull();
1550 if (arguments.size() < 2 || !arguments[0].isString() || !arguments[1].isBool())
1551 return;
1552 WebView::addUserStyleSheet(
1553 cppVariantToWebString(arguments[0]), WebVector<WebString>(),
1554 arguments[1].toBoolean() ? WebView::UserContentInjectInAllFrames : WebView::UserContentInjectInTopFrameOnly,
1555 // Chromium defaults to InjectInSubsequentDocuments, but for compatibility
1556 // with the other ports' DRTs, we use UserStyleInjectInExistingDocuments.
1557 WebView::UserStyleInjectInExistingDocuments);
1558 }
1559
setEditingBehavior(const CppArgumentList & arguments,CppVariant * results)1560 void LayoutTestController::setEditingBehavior(const CppArgumentList& arguments, CppVariant* results)
1561 {
1562 string key = arguments[0].toString();
1563 if (key == "mac") {
1564 m_shell->preferences()->editingBehavior = WebSettings::EditingBehaviorMac;
1565 m_shell->applyPreferences();
1566 } else if (key == "win") {
1567 m_shell->preferences()->editingBehavior = WebSettings::EditingBehaviorWin;
1568 m_shell->applyPreferences();
1569 } else if (key == "unix") {
1570 m_shell->preferences()->editingBehavior = WebSettings::EditingBehaviorUnix;
1571 m_shell->applyPreferences();
1572 } else
1573 logErrorToConsole("Passed invalid editing behavior. Should be 'mac', 'win', or 'unix'.");
1574 }
1575
setMockDeviceOrientation(const CppArgumentList & arguments,CppVariant * result)1576 void LayoutTestController::setMockDeviceOrientation(const CppArgumentList& arguments, CppVariant* result)
1577 {
1578 result->setNull();
1579 if (arguments.size() < 6 || !arguments[0].isBool() || !arguments[1].isNumber() || !arguments[2].isBool() || !arguments[3].isNumber() || !arguments[4].isBool() || !arguments[5].isNumber())
1580 return;
1581
1582 WebDeviceOrientation orientation(arguments[0].toBoolean(), arguments[1].toDouble(), arguments[2].toBoolean(), arguments[3].toDouble(), arguments[4].toBoolean(), arguments[5].toDouble());
1583 // Note that we only call setOrientation on the main page's mock since this is all that the
1584 // tests require. If necessary, we could get a list of WebViewHosts from the TestShell and
1585 // call setOrientation on each DeviceOrientationClientMock.
1586 m_shell->webViewHost()->deviceOrientationClientMock()->setOrientation(orientation);
1587 }
1588
1589 // FIXME: For greater test flexibility, we should be able to set each page's geolocation mock individually.
1590 // https://bugs.webkit.org/show_bug.cgi?id=52368
setGeolocationPermission(const CppArgumentList & arguments,CppVariant * result)1591 void LayoutTestController::setGeolocationPermission(const CppArgumentList& arguments, CppVariant* result)
1592 {
1593 result->setNull();
1594 if (arguments.size() < 1 || !arguments[0].isBool())
1595 return;
1596 Vector<WebViewHost*> windowList = m_shell->windowList();
1597 for (size_t i = 0; i < windowList.size(); i++)
1598 windowList[i]->geolocationClientMock()->setPermission(arguments[0].toBoolean());
1599 }
1600
setMockGeolocationPosition(const CppArgumentList & arguments,CppVariant * result)1601 void LayoutTestController::setMockGeolocationPosition(const CppArgumentList& arguments, CppVariant* result)
1602 {
1603 result->setNull();
1604 if (arguments.size() < 3 || !arguments[0].isNumber() || !arguments[1].isNumber() || !arguments[2].isNumber())
1605 return;
1606 Vector<WebViewHost*> windowList = m_shell->windowList();
1607 for (size_t i = 0; i < windowList.size(); i++)
1608 windowList[i]->geolocationClientMock()->setPosition(arguments[0].toDouble(), arguments[1].toDouble(), arguments[2].toDouble());
1609 }
1610
setMockGeolocationError(const CppArgumentList & arguments,CppVariant * result)1611 void LayoutTestController::setMockGeolocationError(const CppArgumentList& arguments, CppVariant* result)
1612 {
1613 result->setNull();
1614 if (arguments.size() < 2 || !arguments[0].isNumber() || !arguments[1].isString())
1615 return;
1616 Vector<WebViewHost*> windowList = m_shell->windowList();
1617 for (size_t i = 0; i < windowList.size(); i++)
1618 windowList[i]->geolocationClientMock()->setError(arguments[0].toInt32(), cppVariantToWebString(arguments[1]));
1619 }
1620
abortModal(const CppArgumentList & arguments,CppVariant * result)1621 void LayoutTestController::abortModal(const CppArgumentList& arguments, CppVariant* result)
1622 {
1623 result->setNull();
1624 }
1625
addMockSpeechInputResult(const CppArgumentList & arguments,CppVariant * result)1626 void LayoutTestController::addMockSpeechInputResult(const CppArgumentList& arguments, CppVariant* result)
1627 {
1628 result->setNull();
1629 if (arguments.size() < 3 || !arguments[0].isString() || !arguments[1].isNumber() || !arguments[2].isString())
1630 return;
1631
1632 m_shell->webViewHost()->speechInputControllerMock()->addMockRecognitionResult(cppVariantToWebString(arguments[0]), arguments[1].toDouble(), cppVariantToWebString(arguments[2]));
1633 }
1634
layerTreeAsText(const CppArgumentList & args,CppVariant * result)1635 void LayoutTestController::layerTreeAsText(const CppArgumentList& args, CppVariant* result)
1636 {
1637 result->set(m_shell->webView()->mainFrame()->layerTreeAsText(m_showDebugLayerTree).utf8());
1638 }
1639
markerTextForListItem(const CppArgumentList & args,CppVariant * result)1640 void LayoutTestController::markerTextForListItem(const CppArgumentList& args, CppVariant* result)
1641 {
1642 WebElement element;
1643 if (!WebBindings::getElement(args[0].value.objectValue, &element))
1644 result->setNull();
1645 else
1646 result->set(element.document().frame()->markerTextForListItem(element).utf8());
1647 }
1648
hasSpellingMarker(const CppArgumentList & arguments,CppVariant * result)1649 void LayoutTestController::hasSpellingMarker(const CppArgumentList& arguments, CppVariant* result)
1650 {
1651 if (arguments.size() < 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
1652 return;
1653 result->set(m_shell->webView()->mainFrame()->selectionStartHasSpellingMarkerFor(arguments[0].toInt32(), arguments[1].toInt32()));
1654 }
1655
setMinimumTimerInterval(const CppArgumentList & arguments,CppVariant * result)1656 void LayoutTestController::setMinimumTimerInterval(const CppArgumentList& arguments, CppVariant* result)
1657 {
1658 result->setNull();
1659 if (arguments.size() < 1 || !arguments[0].isNumber())
1660 return;
1661 m_shell->webView()->settings()->setMinimumTimerInterval(arguments[0].toDouble());
1662 }
1663
setAutofilled(const CppArgumentList & arguments,CppVariant * result)1664 void LayoutTestController::setAutofilled(const CppArgumentList& arguments, CppVariant* result)
1665 {
1666 result->setNull();
1667 if (arguments.size() != 2 || !arguments[1].isBool())
1668 return;
1669
1670 WebElement element;
1671 if (!WebBindings::getElement(arguments[0].value.objectValue, &element))
1672 return;
1673
1674 WebInputElement* input = toWebInputElement(&element);
1675 if (!input)
1676 return;
1677
1678 input->setAutofilled(arguments[1].value.boolValue);
1679 }
1680
setValueForUser(const CppArgumentList & arguments,CppVariant * result)1681 void LayoutTestController::setValueForUser(const CppArgumentList& arguments, CppVariant* result)
1682 {
1683 result->setNull();
1684 if (arguments.size() != 2)
1685 return;
1686
1687 WebElement element;
1688 if (!WebBindings::getElement(arguments[0].value.objectValue, &element))
1689 return;
1690
1691 WebInputElement* input = toWebInputElement(&element);
1692 if (!input)
1693 return;
1694
1695 input->setValue(cppVariantToWebString(arguments[1]), true);
1696 }
1697
deleteAllLocalStorage(const CppArgumentList & arguments,CppVariant *)1698 void LayoutTestController::deleteAllLocalStorage(const CppArgumentList& arguments, CppVariant*)
1699 {
1700 // Not Implemented
1701 }
1702
originsWithLocalStorage(const CppArgumentList & arguments,CppVariant *)1703 void LayoutTestController::originsWithLocalStorage(const CppArgumentList& arguments, CppVariant*)
1704 {
1705 // Not Implemented
1706 }
1707
deleteLocalStorageForOrigin(const CppArgumentList & arguments,CppVariant *)1708 void LayoutTestController::deleteLocalStorageForOrigin(const CppArgumentList& arguments, CppVariant*)
1709 {
1710 // Not Implemented
1711 }
1712
observeStorageTrackerNotifications(const CppArgumentList &,CppVariant *)1713 void LayoutTestController::observeStorageTrackerNotifications(const CppArgumentList&, CppVariant*)
1714 {
1715 // Not Implemented
1716 }
1717
syncLocalStorage(const CppArgumentList &,CppVariant *)1718 void LayoutTestController::syncLocalStorage(const CppArgumentList&, CppVariant*)
1719 {
1720 // Not Implemented
1721 }
1722
setPluginsEnabled(const CppArgumentList & arguments,CppVariant * result)1723 void LayoutTestController::setPluginsEnabled(const CppArgumentList& arguments, CppVariant* result)
1724 {
1725 if (arguments.size() > 0 && arguments[0].isBool()) {
1726 m_shell->preferences()->pluginsEnabled = arguments[0].toBoolean();
1727 m_shell->applyPreferences();
1728 }
1729 result->setNull();
1730 }
1731