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