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