Source/WebCore: Move setAutofilled from TestRunner to WebCore
[WebKit-https.git] / Tools / DumpRenderTree / chromium / TestRunner / src / TestRunner.cpp
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  * Copyright (C) 2010 Pawel Hajdan (phajdan.jr@chromium.org)
4  * Copyright (C) 2012 Apple Inc. All Rights Reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following disclaimer
14  * in the documentation and/or other materials provided with the
15  * distribution.
16  *     * Neither the name of Google Inc. nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "config.h"
34 #include "TestRunner.h"
35
36 #include "MockWebSpeechInputController.h"
37 #include "MockWebSpeechRecognizer.h"
38 #include "NotificationPresenter.h"
39 #include "TestInterfaces.h"
40 #include "WebBindings.h"
41 #include "WebDataSource.h"
42 #include "WebDeviceOrientation.h"
43 #include "WebDeviceOrientationClientMock.h"
44 #include "WebDocument.h"
45 #include "WebElement.h"
46 #include "WebFindOptions.h"
47 #include "WebFrame.h"
48 #include "WebGeolocationClientMock.h"
49 #include "WebInputElement.h"
50 #include "WebPermissions.h"
51 #include "WebPreferences.h"
52 #include "WebScriptSource.h"
53 #include "WebSecurityPolicy.h"
54 #include "WebSerializedScriptValue.h"
55 #include "WebSettings.h"
56 #include "WebSurroundingText.h"
57 #include "WebTask.h"
58 #include "WebTestDelegate.h"
59 #include "WebTestProxy.h"
60 #include "WebView.h"
61 #include "v8/include/v8.h"
62 #include <limits>
63 #include <memory>
64 #include <public/WebData.h>
65 #include <public/WebPoint.h>
66 #include <public/WebURLResponse.h>
67
68 #if defined(__linux__) || defined(ANDROID)
69 #include "linux/WebFontRendering.h"
70 #endif
71
72 using namespace WebKit;
73 using namespace std;
74
75 namespace WebTestRunner {
76
77 namespace {
78
79 class InvokeCallbackTask : public WebMethodTask<TestRunner> {
80 public:
81     InvokeCallbackTask(TestRunner* object, auto_ptr<CppVariant> callbackArguments)
82         : WebMethodTask<TestRunner>(object)
83         , m_callbackArguments(callbackArguments)
84     {
85     }
86
87     virtual void runIfValid()
88     {
89         CppVariant invokeResult;
90         m_callbackArguments->invokeDefault(m_callbackArguments.get(), 1, invokeResult);
91     }
92
93 private:
94     auto_ptr<CppVariant> m_callbackArguments;
95 };
96
97 }
98
99 TestRunner::WorkQueue::~WorkQueue()
100 {
101     reset();
102 }
103
104 void TestRunner::WorkQueue::processWorkSoon()
105 {
106     if (m_controller->topLoadingFrame())
107         return;
108
109     if (!m_queue.empty()) {
110         // We delay processing queued work to avoid recursion problems.
111         m_controller->m_delegate->postTask(new WorkQueueTask(this));
112     } else if (!m_controller->m_waitUntilDone)
113         m_controller->m_delegate->testFinished();
114 }
115
116 void TestRunner::WorkQueue::processWork()
117 {
118     // Quit doing work once a load is in progress.
119     while (!m_queue.empty()) {
120         bool startedLoad = m_queue.front()->run(m_controller->m_delegate, m_controller->m_webView);
121         delete m_queue.front();
122         m_queue.pop_front();
123         if (startedLoad)
124             return;
125     }
126
127     if (!m_controller->m_waitUntilDone && !m_controller->topLoadingFrame())
128         m_controller->m_delegate->testFinished();
129 }
130
131 void TestRunner::WorkQueue::reset()
132 {
133     m_frozen = false;
134     while (!m_queue.empty()) {
135         delete m_queue.front();
136         m_queue.pop_front();
137     }
138 }
139
140 void TestRunner::WorkQueue::addWork(WorkItem* work)
141 {
142     if (m_frozen) {
143         delete work;
144         return;
145     }
146     m_queue.push_back(work);
147 }
148
149
150 TestRunner::TestRunner(TestInterfaces* interfaces)
151     : m_testIsRunning(false)
152     , m_closeRemainingWindows(false)
153     , m_workQueue(this)
154     , m_testInterfaces(interfaces)
155     , m_delegate(0)
156     , m_webView(0)
157     , m_webPermissions(new WebPermissions)
158 #if ENABLE_NOTIFICATIONS
159     , m_notificationPresenter(new NotificationPresenter)
160 #endif
161 {
162     // Initialize the map that associates methods of this class with the names
163     // they will use when called by JavaScript. The actual binding of those
164     // names to their methods will be done by calling bindToJavaScript() (defined
165     // by CppBoundClass, the parent to TestRunner).
166
167     // Methods controlling test execution.
168     bindMethod("notifyDone", &TestRunner::notifyDone);
169     bindMethod("queueBackNavigation", &TestRunner::queueBackNavigation);
170     bindMethod("queueForwardNavigation", &TestRunner::queueForwardNavigation);
171     bindMethod("queueLoadingScript", &TestRunner::queueLoadingScript);
172     bindMethod("queueLoad", &TestRunner::queueLoad);
173     bindMethod("queueLoadHTMLString", &TestRunner::queueLoadHTMLString);
174     bindMethod("queueNonLoadingScript", &TestRunner::queueNonLoadingScript);
175     bindMethod("queueReload", &TestRunner::queueReload);
176     bindMethod("setCloseRemainingWindowsWhenComplete", &TestRunner::setCloseRemainingWindowsWhenComplete);
177     bindMethod("setCustomPolicyDelegate", &TestRunner::setCustomPolicyDelegate);
178     bindMethod("waitForPolicyDelegate", &TestRunner::waitForPolicyDelegate);
179     bindMethod("waitUntilDone", &TestRunner::waitUntilDone);
180     bindMethod("windowCount", &TestRunner::windowCount);
181     // Methods implemented in terms of chromium's public WebKit API.
182     bindMethod("setTabKeyCyclesThroughElements", &TestRunner::setTabKeyCyclesThroughElements);
183     bindMethod("execCommand", &TestRunner::execCommand);
184     bindMethod("isCommandEnabled", &TestRunner::isCommandEnabled);
185     bindMethod("elementDoesAutoCompleteForElementWithId", &TestRunner::elementDoesAutoCompleteForElementWithId);
186     bindMethod("callShouldCloseOnWebView", &TestRunner::callShouldCloseOnWebView);
187     bindMethod("setDomainRelaxationForbiddenForURLScheme", &TestRunner::setDomainRelaxationForbiddenForURLScheme);
188     bindMethod("evaluateScriptInIsolatedWorldAndReturnValue", &TestRunner::evaluateScriptInIsolatedWorldAndReturnValue);
189     bindMethod("evaluateScriptInIsolatedWorld", &TestRunner::evaluateScriptInIsolatedWorld);
190     bindMethod("setIsolatedWorldSecurityOrigin", &TestRunner::setIsolatedWorldSecurityOrigin);
191     bindMethod("setIsolatedWorldContentSecurityPolicy", &TestRunner::setIsolatedWorldContentSecurityPolicy);
192     bindMethod("addOriginAccessWhitelistEntry", &TestRunner::addOriginAccessWhitelistEntry);
193     bindMethod("removeOriginAccessWhitelistEntry", &TestRunner::removeOriginAccessWhitelistEntry);
194     bindMethod("hasCustomPageSizeStyle", &TestRunner::hasCustomPageSizeStyle);
195     bindMethod("forceRedSelectionColors", &TestRunner::forceRedSelectionColors);
196     bindMethod("addUserScript", &TestRunner::addUserScript);
197     bindMethod("addUserStyleSheet", &TestRunner::addUserStyleSheet);
198     bindMethod("startSpeechInput", &TestRunner::startSpeechInput);
199     bindMethod("markerTextForListItem", &TestRunner::markerTextForListItem);
200     bindMethod("findString", &TestRunner::findString);
201     bindMethod("setValueForUser", &TestRunner::setValueForUser);
202     bindMethod("enableFixedLayoutMode", &TestRunner::enableFixedLayoutMode);
203     bindMethod("setFixedLayoutSize", &TestRunner::setFixedLayoutSize);
204     bindMethod("selectionAsMarkup", &TestRunner::selectionAsMarkup);
205     bindMethod("setTextSubpixelPositioning", &TestRunner::setTextSubpixelPositioning);
206     bindMethod("resetPageVisibility", &TestRunner::resetPageVisibility);
207     bindMethod("setPageVisibility", &TestRunner::setPageVisibility);
208     bindMethod("setTextDirection", &TestRunner::setTextDirection);
209     bindMethod("textSurroundingNode", &TestRunner::textSurroundingNode);
210     bindMethod("disableAutoResizeMode", &TestRunner::disableAutoResizeMode);
211     bindMethod("enableAutoResizeMode", &TestRunner::enableAutoResizeMode);
212     bindMethod("setSmartInsertDeleteEnabled", &TestRunner::setSmartInsertDeleteEnabled);
213     bindMethod("setSelectTrailingWhitespaceEnabled", &TestRunner::setSelectTrailingWhitespaceEnabled);
214     bindMethod("setMockDeviceOrientation", &TestRunner::setMockDeviceOrientation);
215     bindMethod("didAcquirePointerLock", &TestRunner::didAcquirePointerLock);
216     bindMethod("didLosePointerLock", &TestRunner::didLosePointerLock);
217     bindMethod("didNotAcquirePointerLock", &TestRunner::didNotAcquirePointerLock);
218     bindMethod("setPointerLockWillRespondAsynchronously", &TestRunner::setPointerLockWillRespondAsynchronously);
219     bindMethod("setPointerLockWillFailSynchronously", &TestRunner::setPointerLockWillFailSynchronously);
220
221     // The following modify WebPreferences.
222     bindMethod("setUserStyleSheetEnabled", &TestRunner::setUserStyleSheetEnabled);
223     bindMethod("setUserStyleSheetLocation", &TestRunner::setUserStyleSheetLocation);
224     bindMethod("setAuthorAndUserStylesEnabled", &TestRunner::setAuthorAndUserStylesEnabled);
225     bindMethod("setPopupBlockingEnabled", &TestRunner::setPopupBlockingEnabled);
226     bindMethod("setJavaScriptCanAccessClipboard", &TestRunner::setJavaScriptCanAccessClipboard);
227     bindMethod("setXSSAuditorEnabled", &TestRunner::setXSSAuditorEnabled);
228     bindMethod("setAllowUniversalAccessFromFileURLs", &TestRunner::setAllowUniversalAccessFromFileURLs);
229     bindMethod("setAllowFileAccessFromFileURLs", &TestRunner::setAllowFileAccessFromFileURLs);
230     bindMethod("overridePreference", &TestRunner::overridePreference);
231     bindMethod("setPluginsEnabled", &TestRunner::setPluginsEnabled);
232     bindMethod("setAsynchronousSpellCheckingEnabled", &TestRunner::setAsynchronousSpellCheckingEnabled);
233     bindMethod("setTouchDragDropEnabled", &TestRunner::setTouchDragDropEnabled);
234
235     // The following modify the state of the TestRunner.
236     bindMethod("dumpEditingCallbacks", &TestRunner::dumpEditingCallbacks);
237     bindMethod("dumpAsText", &TestRunner::dumpAsText);
238     bindMethod("dumpChildFramesAsText", &TestRunner::dumpChildFramesAsText);
239     bindMethod("dumpChildFrameScrollPositions", &TestRunner::dumpChildFrameScrollPositions);
240     bindMethod("setAudioData", &TestRunner::setAudioData);
241     bindMethod("dumpFrameLoadCallbacks", &TestRunner::dumpFrameLoadCallbacks);
242     bindMethod("dumpUserGestureInFrameLoadCallbacks", &TestRunner::dumpUserGestureInFrameLoadCallbacks);
243     bindMethod("setStopProvisionalFrameLoads", &TestRunner::setStopProvisionalFrameLoads);
244     bindMethod("dumpTitleChanges", &TestRunner::dumpTitleChanges);
245     bindMethod("dumpCreateView", &TestRunner::dumpCreateView);
246     bindMethod("setCanOpenWindows", &TestRunner::setCanOpenWindows);
247     bindMethod("dumpResourceLoadCallbacks", &TestRunner::dumpResourceLoadCallbacks);
248     bindMethod("dumpResourceRequestCallbacks", &TestRunner::dumpResourceRequestCallbacks);
249     bindMethod("dumpResourceResponseMIMETypes", &TestRunner::dumpResourceResponseMIMETypes);
250     bindMethod("dumpPermissionClientCallbacks", &TestRunner::dumpPermissionClientCallbacks);
251     bindMethod("setImagesAllowed", &TestRunner::setImagesAllowed);
252     bindMethod("setScriptsAllowed", &TestRunner::setScriptsAllowed);
253     bindMethod("setStorageAllowed", &TestRunner::setStorageAllowed);
254     bindMethod("setPluginsAllowed", &TestRunner::setPluginsAllowed);
255     bindMethod("setAllowDisplayOfInsecureContent", &TestRunner::setAllowDisplayOfInsecureContent);
256     bindMethod("setAllowRunningOfInsecureContent", &TestRunner::setAllowRunningOfInsecureContent);
257     bindMethod("dumpStatusCallbacks", &TestRunner::dumpWindowStatusChanges);
258     bindMethod("dumpProgressFinishedCallback", &TestRunner::dumpProgressFinishedCallback);
259     bindMethod("dumpBackForwardList", &TestRunner::dumpBackForwardList);
260     bindMethod("setDeferMainResourceDataLoad", &TestRunner::setDeferMainResourceDataLoad);
261     bindMethod("dumpSelectionRect", &TestRunner::dumpSelectionRect);
262     bindMethod("testRepaint", &TestRunner::testRepaint);
263     bindMethod("repaintSweepHorizontally", &TestRunner::repaintSweepHorizontally);
264     bindMethod("setPrinting", &TestRunner::setPrinting);
265     bindMethod("setShouldStayOnPageAfterHandlingBeforeUnload", &TestRunner::setShouldStayOnPageAfterHandlingBeforeUnload);
266     bindMethod("setWillSendRequestClearHeader", &TestRunner::setWillSendRequestClearHeader);
267     bindMethod("setWillSendRequestReturnsNull", &TestRunner::setWillSendRequestReturnsNull);
268     bindMethod("setWillSendRequestReturnsNullOnRedirect", &TestRunner::setWillSendRequestReturnsNullOnRedirect);
269
270     // The following methods interact with the WebTestProxy.
271     // The following methods interact with the WebTestDelegate.
272     bindMethod("showWebInspector", &TestRunner::showWebInspector);
273     bindMethod("closeWebInspector", &TestRunner::closeWebInspector);
274     bindMethod("evaluateInWebInspector", &TestRunner::evaluateInWebInspector);
275     bindMethod("clearAllDatabases", &TestRunner::clearAllDatabases);
276     bindMethod("setDatabaseQuota", &TestRunner::setDatabaseQuota);
277     bindMethod("setAlwaysAcceptCookies", &TestRunner::setAlwaysAcceptCookies);
278     bindMethod("setWindowIsKey", &TestRunner::setWindowIsKey);
279     bindMethod("pathToLocalResource", &TestRunner::pathToLocalResource);
280     bindMethod("setBackingScaleFactor", &TestRunner::setBackingScaleFactor);
281     bindMethod("setPOSIXLocale", &TestRunner::setPOSIXLocale);
282     bindMethod("numberOfPendingGeolocationPermissionRequests", &TestRunner:: numberOfPendingGeolocationPermissionRequests);
283     bindMethod("setGeolocationPermission", &TestRunner::setGeolocationPermission);
284     bindMethod("setMockGeolocationPositionUnavailableError", &TestRunner::setMockGeolocationPositionUnavailableError);
285     bindMethod("setMockGeolocationPosition", &TestRunner::setMockGeolocationPosition);
286 #if ENABLE_NOTIFICATIONS
287     bindMethod("grantWebNotificationPermission", &TestRunner::grantWebNotificationPermission);
288     bindMethod("simulateLegacyWebNotificationClick", &TestRunner::simulateLegacyWebNotificationClick);
289 #endif
290     bindMethod("addMockSpeechInputResult", &TestRunner::addMockSpeechInputResult);
291     bindMethod("setMockSpeechInputDumpRect", &TestRunner::setMockSpeechInputDumpRect);
292     bindMethod("addMockSpeechRecognitionResult", &TestRunner::addMockSpeechRecognitionResult);
293     bindMethod("setMockSpeechRecognitionError", &TestRunner::setMockSpeechRecognitionError);
294     bindMethod("wasMockSpeechRecognitionAborted", &TestRunner::wasMockSpeechRecognitionAborted);
295     bindMethod("display", &TestRunner::display);
296     bindMethod("displayInvalidatedRegion", &TestRunner::displayInvalidatedRegion);
297
298     // Properties.
299     bindProperty("globalFlag", &m_globalFlag);
300     bindProperty("titleTextDirection", &m_titleTextDirection);
301     bindProperty("platformName", &m_platformName);
302     // webHistoryItemCount is used by tests in LayoutTests\http\tests\history
303     bindProperty("webHistoryItemCount", &m_webHistoryItemCount);
304     bindProperty("interceptPostMessage", &m_interceptPostMessage);
305
306     // The following are stubs.
307     bindMethod("dumpDatabaseCallbacks", &TestRunner::notImplemented);
308     bindMethod("denyWebNotificationPermission", &TestRunner::notImplemented);
309     bindMethod("removeAllWebNotificationPermissions", &TestRunner::notImplemented);
310     bindMethod("simulateWebNotificationClick", &TestRunner::notImplemented);
311     bindMethod("setIconDatabaseEnabled", &TestRunner::notImplemented);
312     bindMethod("setScrollbarPolicy", &TestRunner::notImplemented);
313     bindMethod("clearAllApplicationCaches", &TestRunner::notImplemented);
314     bindMethod("clearApplicationCacheForOrigin", &TestRunner::notImplemented);
315     bindMethod("clearBackForwardList", &TestRunner::notImplemented);
316     bindMethod("keepWebHistory", &TestRunner::notImplemented);
317     bindMethod("setApplicationCacheOriginQuota", &TestRunner::notImplemented);
318     bindMethod("setCallCloseOnWebViews", &TestRunner::notImplemented);
319     bindMethod("setMainFrameIsFirstResponder", &TestRunner::notImplemented);
320     bindMethod("setPrivateBrowsingEnabled", &TestRunner::notImplemented);
321     bindMethod("setUseDashboardCompatibilityMode", &TestRunner::notImplemented);
322     bindMethod("deleteAllLocalStorage", &TestRunner::notImplemented);
323     bindMethod("localStorageDiskUsageForOrigin", &TestRunner::notImplemented);
324     bindMethod("originsWithLocalStorage", &TestRunner::notImplemented);
325     bindMethod("deleteLocalStorageForOrigin", &TestRunner::notImplemented);
326     bindMethod("observeStorageTrackerNotifications", &TestRunner::notImplemented);
327     bindMethod("syncLocalStorage", &TestRunner::notImplemented);
328     bindMethod("addDisallowedURL", &TestRunner::notImplemented);
329     bindMethod("applicationCacheDiskUsageForOrigin", &TestRunner::notImplemented);
330     bindMethod("abortModal", &TestRunner::notImplemented);
331
332     // The fallback method is called when an unknown method is invoked.
333     bindFallbackMethod(&TestRunner::fallbackMethod);
334 }
335
336 TestRunner::~TestRunner()
337 {
338 }
339
340 void TestRunner::setDelegate(WebTestDelegate* delegate)
341 {
342     m_delegate = delegate;
343     m_webPermissions->setDelegate(delegate);
344 #if ENABLE_NOTIFICATIONS
345     m_notificationPresenter->setDelegate(delegate);
346 #endif
347 }
348
349 void TestRunner::setWebView(WebView* webView, WebTestProxyBase* proxy)
350 {
351     m_webView = webView;
352     m_proxy = proxy;
353 }
354
355 void TestRunner::reset()
356 {
357     if (m_webView) {
358         m_webView->setZoomLevel(false, 0);
359         m_webView->setTabKeyCyclesThroughElements(true);
360 #if !defined(__APPLE__) && !defined(WIN32) // Actually, TOOLKIT_GTK
361         // (Constants copied because we can't depend on the header that defined
362         // them from this file.)
363         m_webView->setSelectionColors(0xff1e90ff, 0xff000000, 0xffc8c8c8, 0xff323232);
364 #endif
365         m_webView->removeAllUserContent();
366         m_webView->disableAutoResizeMode();
367     }
368     m_topLoadingFrame = 0;
369     m_waitUntilDone = false;
370     m_policyDelegateEnabled = false;
371     m_policyDelegateIsPermissive = false;
372     m_policyDelegateShouldNotifyDone = false;
373
374     WebSecurityPolicy::resetOriginAccessWhitelists();
375 #if defined(__linux__) || defined(ANDROID)
376     WebFontRendering::setSubpixelPositioning(false);
377 #endif
378
379     if (m_delegate) {
380         // Reset the default quota for each origin to 5MB
381         m_delegate->setDatabaseQuota(5 * 1024 * 1024);
382         m_delegate->setDeviceScaleFactor(1);
383         m_delegate->setAcceptAllCookies(false);
384         m_delegate->setLocale("");
385     }
386
387     m_dumpEditingCallbacks = false;
388     m_dumpAsText = false;
389     m_generatePixelResults = true;
390     m_dumpChildFrameScrollPositions = false;
391     m_dumpChildFramesAsText = false;
392     m_dumpAsAudio = false;
393     m_dumpFrameLoadCallbacks = false;
394     m_dumpUserGestureInFrameLoadCallbacks = false;
395     m_stopProvisionalFrameLoads = false;
396     m_dumpTitleChanges = false;
397     m_dumpCreateView = false;
398     m_canOpenWindows = false;
399     m_dumpResourceLoadCallbacks = false;
400     m_dumpResourceRequestCallbacks = false;
401     m_dumpResourceResponseMIMETypes = false;
402     m_dumpWindowStatusChanges = false;
403     m_dumpProgressFinishedCallback = false;
404     m_dumpBackForwardList = false;
405     m_deferMainResourceDataLoad = true;
406     m_dumpSelectionRect = false;
407     m_testRepaint = false;
408     m_sweepHorizontally = false;
409     m_isPrinting = false;
410     m_shouldStayOnPageAfterHandlingBeforeUnload = false;
411     m_shouldBlockRedirects = false;
412     m_willSendRequestShouldReturnNull = false;
413     m_smartInsertDeleteEnabled = true;
414 #ifdef WIN32
415     m_selectTrailingWhitespaceEnabled = true;
416 #else
417     m_selectTrailingWhitespaceEnabled = false;
418 #endif
419
420     m_httpHeadersToClear.clear();
421
422     m_globalFlag.set(false);
423     m_titleTextDirection.set("ltr");
424     m_webHistoryItemCount.set(0);
425     m_interceptPostMessage.set(false);
426     m_platformName.set("chromium");
427
428     m_userStyleSheetLocation = WebURL();
429
430     m_webPermissions->reset();
431
432 #if ENABLE_NOTIFICATIONS
433     m_notificationPresenter->reset();
434 #endif
435     m_pointerLocked = false;
436     m_pointerLockPlannedResult = PointerLockWillSucceed;
437
438     m_taskList.revokeAll();
439     m_workQueue.reset();
440
441     if (m_closeRemainingWindows && m_delegate)
442         m_delegate->closeRemainingWindows();
443     else
444         m_closeRemainingWindows = true;
445 }
446
447
448 void TestRunner::setTestIsRunning(bool running)
449 {
450     m_testIsRunning = running;
451 }
452
453 bool TestRunner::shouldDumpEditingCallbacks() const
454 {
455     return m_dumpEditingCallbacks;
456 }
457
458 void TestRunner::checkResponseMimeType()
459 {
460     // Text output: the test page can request different types of output
461     // which we handle here.
462     if (!m_dumpAsText) {
463         string mimeType = m_webView->mainFrame()->dataSource()->response().mimeType().utf8();
464         if (mimeType == "text/plain") {
465             m_dumpAsText = true;
466             m_generatePixelResults = false;
467         }
468     }
469 }
470
471 bool TestRunner::shouldDumpAsText()
472 {
473     checkResponseMimeType();
474     return m_dumpAsText;
475 }
476
477 void TestRunner::setShouldDumpAsText(bool value)
478 {
479     m_dumpAsText = value;
480 }
481
482 bool TestRunner::shouldGeneratePixelResults()
483 {
484     checkResponseMimeType();
485     return m_generatePixelResults;
486 }
487
488 void TestRunner::setShouldGeneratePixelResults(bool value)
489 {
490     m_generatePixelResults = value;
491 }
492
493 bool TestRunner::shouldDumpChildFrameScrollPositions() const
494 {
495     return m_dumpChildFrameScrollPositions;
496 }
497
498 bool TestRunner::shouldDumpChildFramesAsText() const
499 {
500     return m_dumpChildFramesAsText;
501 }
502
503 bool TestRunner::shouldDumpAsAudio() const
504 {
505     return m_dumpAsAudio;
506 }
507
508 const WebArrayBufferView* TestRunner::audioData() const
509 {
510     return &m_audioData;
511 }
512
513 bool TestRunner::shouldDumpFrameLoadCallbacks() const
514 {
515     return m_testIsRunning && m_dumpFrameLoadCallbacks;
516 }
517
518 void TestRunner::setShouldDumpFrameLoadCallbacks(bool value)
519 {
520     m_dumpFrameLoadCallbacks = value;
521 }
522
523 bool TestRunner::shouldDumpUserGestureInFrameLoadCallbacks() const
524 {
525     return m_testIsRunning && m_dumpUserGestureInFrameLoadCallbacks;
526 }
527
528 bool TestRunner::stopProvisionalFrameLoads() const
529 {
530     return m_stopProvisionalFrameLoads;
531 }
532
533 bool TestRunner::shouldDumpTitleChanges() const
534 {
535     return m_dumpTitleChanges;
536 }
537
538 bool TestRunner::shouldDumpCreateView() const
539 {
540     return m_dumpCreateView;
541 }
542
543 bool TestRunner::canOpenWindows() const
544 {
545     return m_canOpenWindows;
546 }
547
548 bool TestRunner::shouldDumpResourceLoadCallbacks() const
549 {
550     return m_testIsRunning && m_dumpResourceLoadCallbacks;
551 }
552
553 bool TestRunner::shouldDumpResourceRequestCallbacks() const
554 {
555     return m_testIsRunning && m_dumpResourceRequestCallbacks;
556 }
557
558 bool TestRunner::shouldDumpResourceResponseMIMETypes() const
559 {
560     return m_testIsRunning && m_dumpResourceResponseMIMETypes;
561 }
562
563 WebPermissionClient* TestRunner::webPermissions() const
564 {
565     return m_webPermissions.get();
566 }
567
568 bool TestRunner::shouldDumpStatusCallbacks() const
569 {
570     return m_dumpWindowStatusChanges;
571 }
572
573 bool TestRunner::shouldDumpProgressFinishedCallback() const
574 {
575     return m_dumpProgressFinishedCallback;
576 }
577
578 bool TestRunner::shouldDumpBackForwardList() const
579 {
580     return m_dumpBackForwardList;
581 }
582
583 bool TestRunner::deferMainResourceDataLoad() const
584 {
585     return m_deferMainResourceDataLoad;
586 }
587
588 bool TestRunner::shouldDumpSelectionRect() const
589 {
590     return m_dumpSelectionRect;
591 }
592
593 bool TestRunner::testRepaint() const
594 {
595     return m_testRepaint;
596 }
597
598 bool TestRunner::sweepHorizontally() const
599 {
600     return m_sweepHorizontally;
601 }
602
603 bool TestRunner::isPrinting() const
604 {
605     return m_isPrinting;
606 }
607
608 bool TestRunner::shouldStayOnPageAfterHandlingBeforeUnload() const
609 {
610     return m_shouldStayOnPageAfterHandlingBeforeUnload;
611 }
612
613 void TestRunner::setTitleTextDirection(WebKit::WebTextDirection dir)
614 {
615     m_titleTextDirection.set(dir == WebKit::WebTextDirectionLeftToRight ? "ltr" : "rtl");
616 }
617
618 const std::set<std::string>* TestRunner::httpHeadersToClear() const
619 {
620     return &m_httpHeadersToClear;
621 }
622
623 bool TestRunner::shouldBlockRedirects() const
624 {
625     return m_shouldBlockRedirects;
626 }
627
628 bool TestRunner::willSendRequestShouldReturnNull() const
629 {
630     return m_willSendRequestShouldReturnNull;
631 }
632
633 void TestRunner::setTopLoadingFrame(WebFrame* frame, bool clear)
634 {
635     if (frame->top()->view() != m_webView)
636         return;
637     if (clear) {
638         m_topLoadingFrame = 0;
639         locationChangeDone();
640     } else if (!m_topLoadingFrame)
641         m_topLoadingFrame = frame;
642 }
643
644 WebFrame* TestRunner::topLoadingFrame() const
645 {
646     return m_topLoadingFrame;
647 }
648
649 void TestRunner::policyDelegateDone()
650 {
651     WEBKIT_ASSERT(m_waitUntilDone);
652     m_delegate->testFinished();
653     m_waitUntilDone = false;
654 }
655
656 bool TestRunner::policyDelegateEnabled() const
657 {
658     return m_policyDelegateEnabled;
659 }
660
661 bool TestRunner::policyDelegateIsPermissive() const
662 {
663     return m_policyDelegateIsPermissive;
664 }
665
666 bool TestRunner::policyDelegateShouldNotifyDone() const
667 {
668     return m_policyDelegateShouldNotifyDone;
669 }
670
671 bool TestRunner::shouldInterceptPostMessage() const
672 {
673     return m_interceptPostMessage.isBool() && m_interceptPostMessage.toBoolean();
674 }
675
676 bool TestRunner::isSmartInsertDeleteEnabled() const
677 {
678     return m_smartInsertDeleteEnabled;
679 }
680
681 bool TestRunner::isSelectTrailingWhitespaceEnabled() const
682 {
683     return m_selectTrailingWhitespaceEnabled;
684 }
685
686 #if ENABLE_NOTIFICATIONS
687 WebNotificationPresenter* TestRunner::notificationPresenter() const
688 {
689     return m_notificationPresenter.get();
690 }
691 #endif
692
693 bool TestRunner::requestPointerLock()
694 {
695     switch (m_pointerLockPlannedResult) {
696     case PointerLockWillSucceed:
697         m_delegate->postDelayedTask(new HostMethodTask(this, &TestRunner::didAcquirePointerLockInternal), 0);
698         return true;
699     case PointerLockWillRespondAsync:
700         WEBKIT_ASSERT(!m_pointerLocked);
701         return true;
702     case PointerLockWillFailSync:
703         WEBKIT_ASSERT(!m_pointerLocked);
704         return false;
705     default:
706         WEBKIT_ASSERT_NOT_REACHED();
707         return false;
708     }
709 }
710
711 void TestRunner::requestPointerUnlock()
712 {
713     m_delegate->postDelayedTask(new HostMethodTask(this, &TestRunner::didLosePointerLockInternal), 0);
714 }
715
716 bool TestRunner::isPointerLocked()
717 {
718     return m_pointerLocked;
719 }
720
721 void TestRunner::didAcquirePointerLockInternal()
722 {
723     m_pointerLocked = true;
724     m_webView->didAcquirePointerLock();
725
726     // Reset planned result to default.
727     m_pointerLockPlannedResult = PointerLockWillSucceed;
728 }
729
730 void TestRunner::didNotAcquirePointerLockInternal()
731 {
732     WEBKIT_ASSERT(!m_pointerLocked);
733     m_pointerLocked = false;
734     m_webView->didNotAcquirePointerLock();
735
736     // Reset planned result to default.
737     m_pointerLockPlannedResult = PointerLockWillSucceed;
738 }
739
740 void TestRunner::didLosePointerLockInternal()
741 {
742     bool wasLocked = m_pointerLocked;
743     m_pointerLocked = false;
744     if (wasLocked)
745         m_webView->didLosePointerLock();
746 }
747
748 void TestRunner::showDevTools()
749 {
750     m_delegate->showDevTools();
751 }
752
753 void TestRunner::waitUntilDone(const CppArgumentList&, CppVariant* result)
754 {
755     if (!m_delegate->isBeingDebugged())
756         m_delegate->postDelayedTask(new NotifyDoneTimedOutTask(this), m_delegate->layoutTestTimeout());
757     m_waitUntilDone = true;
758     result->setNull();
759 }
760
761 void TestRunner::notifyDone(const CppArgumentList&, CppVariant* result)
762 {
763     // Test didn't timeout. Kill the timeout timer.
764     taskList()->revokeAll();
765
766     completeNotifyDone(false);
767     result->setNull();
768 }
769
770 void TestRunner::completeNotifyDone(bool isTimeout)
771 {
772     if (m_waitUntilDone && !topLoadingFrame() && m_workQueue.isEmpty()) {
773         if (isTimeout)
774             m_delegate->testTimedOut();
775         else
776             m_delegate->testFinished();
777     }
778     m_waitUntilDone = false;
779 }
780
781 class WorkItemBackForward : public TestRunner::WorkItem {
782 public:
783     WorkItemBackForward(int distance) : m_distance(distance) { }
784     bool run(WebTestDelegate* delegate, WebView*)
785     {
786         delegate->goToOffset(m_distance);
787         return true; // FIXME: Did it really start a navigation?
788     }
789
790 private:
791     int m_distance;
792 };
793
794 void TestRunner::queueBackNavigation(const CppArgumentList& arguments, CppVariant* result)
795 {
796     if (arguments.size() > 0 && arguments[0].isNumber())
797         m_workQueue.addWork(new WorkItemBackForward(-arguments[0].toInt32()));
798     result->setNull();
799 }
800
801 void TestRunner::queueForwardNavigation(const CppArgumentList& arguments, CppVariant* result)
802 {
803     if (arguments.size() > 0 && arguments[0].isNumber())
804         m_workQueue.addWork(new WorkItemBackForward(arguments[0].toInt32()));
805     result->setNull();
806 }
807
808 class WorkItemReload : public TestRunner::WorkItem {
809 public:
810     bool run(WebTestDelegate* delegate, WebView*)
811     {
812         delegate->reload();
813         return true;
814     }
815 };
816
817 void TestRunner::queueReload(const CppArgumentList&, CppVariant* result)
818 {
819     m_workQueue.addWork(new WorkItemReload);
820     result->setNull();
821 }
822
823 class WorkItemLoadingScript : public TestRunner::WorkItem {
824 public:
825     WorkItemLoadingScript(const string& script) : m_script(script) { }
826     bool run(WebTestDelegate*, WebView* webView)
827     {
828         webView->mainFrame()->executeScript(WebScriptSource(WebString::fromUTF8(m_script)));
829         return true; // FIXME: Did it really start a navigation?
830     }
831
832 private:
833     string m_script;
834 };
835
836 class WorkItemNonLoadingScript : public TestRunner::WorkItem {
837 public:
838     WorkItemNonLoadingScript(const string& script) : m_script(script) { }
839     bool run(WebTestDelegate*, WebView* webView)
840     {
841         webView->mainFrame()->executeScript(WebScriptSource(WebString::fromUTF8(m_script)));
842         return false;
843     }
844
845 private:
846     string m_script;
847 };
848
849 void TestRunner::queueLoadingScript(const CppArgumentList& arguments, CppVariant* result)
850 {
851     if (arguments.size() > 0 && arguments[0].isString())
852         m_workQueue.addWork(new WorkItemLoadingScript(arguments[0].toString()));
853     result->setNull();
854 }
855
856 void TestRunner::queueNonLoadingScript(const CppArgumentList& arguments, CppVariant* result)
857 {
858     if (arguments.size() > 0 && arguments[0].isString())
859         m_workQueue.addWork(new WorkItemNonLoadingScript(arguments[0].toString()));
860     result->setNull();
861 }
862
863 class WorkItemLoad : public TestRunner::WorkItem {
864 public:
865     WorkItemLoad(const WebURL& url, const string& target)
866         : m_url(url)
867         , m_target(target) { }
868     bool run(WebTestDelegate* delegate, WebView*)
869     {
870         delegate->loadURLForFrame(m_url, m_target);
871         return true; // FIXME: Did it really start a navigation?
872     }
873
874 private:
875     WebURL m_url;
876     string m_target;
877 };
878
879 void TestRunner::queueLoad(const CppArgumentList& arguments, CppVariant* result)
880 {
881     if (arguments.size() > 0 && arguments[0].isString()) {
882         // FIXME: Implement WebURL::resolve() and avoid GURL.
883         GURL currentURL = m_webView->mainFrame()->document().url();
884         GURL fullURL = currentURL.Resolve(arguments[0].toString());
885
886         string target = "";
887         if (arguments.size() > 1 && arguments[1].isString())
888             target = arguments[1].toString();
889
890         m_workQueue.addWork(new WorkItemLoad(fullURL, target));
891     }
892     result->setNull();
893 }
894
895 class WorkItemLoadHTMLString : public TestRunner::WorkItem  {
896 public:
897     WorkItemLoadHTMLString(const std::string& html, const WebURL& baseURL)
898         : m_html(html)
899         , m_baseURL(baseURL) { }
900     WorkItemLoadHTMLString(const std::string& html, const WebURL& baseURL, const WebURL& unreachableURL)
901         : m_html(html)
902         , m_baseURL(baseURL)
903         , m_unreachableURL(unreachableURL) { }
904     bool run(WebTestDelegate*, WebView* webView)
905     {
906         webView->mainFrame()->loadHTMLString(
907             WebKit::WebData(m_html.data(), m_html.length()), m_baseURL, m_unreachableURL);
908         return true;
909     }
910
911 private:
912     std::string m_html;
913     WebURL m_baseURL;
914     WebURL m_unreachableURL;
915 };
916
917 void TestRunner::queueLoadHTMLString(const CppArgumentList& arguments, CppVariant* result)
918 {
919     if (arguments.size() > 0 && arguments[0].isString()) {
920         string html = arguments[0].toString();
921         WebURL baseURL(GURL(""));
922         if (arguments.size() > 1 && arguments[1].isString())
923             baseURL = WebURL(GURL(arguments[1].toString()));
924         if (arguments.size() > 2 && arguments[2].isString())
925             m_workQueue.addWork(new WorkItemLoadHTMLString(html, baseURL, WebURL(GURL(arguments[2].toString()))));
926         else
927             m_workQueue.addWork(new WorkItemLoadHTMLString(html, baseURL));
928     }
929     result->setNull();
930 }
931
932 void TestRunner::locationChangeDone()
933 {
934     m_webHistoryItemCount.set(m_delegate->navigationEntryCount());
935
936     // No more new work after the first complete load.
937     m_workQueue.setFrozen(true);
938
939     if (!m_waitUntilDone)
940         m_workQueue.processWorkSoon();
941 }
942
943 void TestRunner::windowCount(const CppArgumentList&, CppVariant* result)
944 {
945     result->set(static_cast<int>(m_testInterfaces->windowList().size()));
946 }
947
948 void TestRunner::setCloseRemainingWindowsWhenComplete(const CppArgumentList& arguments, CppVariant* result)
949 {
950     if (arguments.size() > 0 && arguments[0].isBool())
951         m_closeRemainingWindows = arguments[0].value.boolValue;
952     result->setNull();
953 }
954
955 void TestRunner::setCustomPolicyDelegate(const CppArgumentList& arguments, CppVariant* result)
956 {
957     if (arguments.size() > 0 && arguments[0].isBool()) {
958         m_policyDelegateEnabled = arguments[0].value.boolValue;
959         m_policyDelegateIsPermissive = false;
960         if (arguments.size() > 1 && arguments[1].isBool())
961             m_policyDelegateIsPermissive = arguments[1].value.boolValue;
962     }
963     result->setNull();
964 }
965
966 void TestRunner::waitForPolicyDelegate(const CppArgumentList&, CppVariant* result)
967 {
968     m_policyDelegateEnabled = true;
969     m_policyDelegateShouldNotifyDone = true;
970     m_waitUntilDone = true;
971     result->setNull();
972 }
973
974 void TestRunner::dumpPermissionClientCallbacks(const CppArgumentList&, CppVariant* result)
975 {
976     m_webPermissions->setDumpCallbacks(true);
977     result->setNull();
978 }
979
980 void TestRunner::setImagesAllowed(const CppArgumentList& arguments, CppVariant* result)
981 {
982     if (arguments.size() > 0 && arguments[0].isBool())
983         m_webPermissions->setImagesAllowed(arguments[0].toBoolean());
984     result->setNull();
985 }
986
987 void TestRunner::setScriptsAllowed(const CppArgumentList& arguments, CppVariant* result)
988 {
989     if (arguments.size() > 0 && arguments[0].isBool())
990         m_webPermissions->setScriptsAllowed(arguments[0].toBoolean());
991     result->setNull();
992 }
993
994 void TestRunner::setStorageAllowed(const CppArgumentList& arguments, CppVariant* result)
995 {
996     if (arguments.size() > 0 && arguments[0].isBool())
997         m_webPermissions->setStorageAllowed(arguments[0].toBoolean());
998     result->setNull();
999 }
1000
1001 void TestRunner::setPluginsAllowed(const CppArgumentList& arguments, CppVariant* result)
1002 {
1003     if (arguments.size() > 0 && arguments[0].isBool())
1004         m_webPermissions->setPluginsAllowed(arguments[0].toBoolean());
1005     result->setNull();
1006 }
1007
1008 void TestRunner::setAllowDisplayOfInsecureContent(const CppArgumentList& arguments, CppVariant* result)
1009 {
1010     if (arguments.size() > 0 && arguments[0].isBool())
1011         m_webPermissions->setDisplayingInsecureContentAllowed(arguments[0].toBoolean());
1012
1013     result->setNull();
1014 }
1015
1016 void TestRunner::setAllowRunningOfInsecureContent(const CppArgumentList& arguments, CppVariant* result)
1017 {
1018     if (arguments.size() > 0 && arguments[0].isBool())
1019         m_webPermissions->setRunningInsecureContentAllowed(arguments[0].value.boolValue);
1020
1021     result->setNull();
1022 }
1023
1024 void TestRunner::dumpWindowStatusChanges(const CppArgumentList&, CppVariant* result)
1025 {
1026     m_dumpWindowStatusChanges = true;
1027     result->setNull();
1028 }
1029
1030 void TestRunner::dumpProgressFinishedCallback(const CppArgumentList&, CppVariant* result)
1031 {
1032     m_dumpProgressFinishedCallback = true;
1033     result->setNull();
1034 }
1035
1036 void TestRunner::dumpBackForwardList(const CppArgumentList&, CppVariant* result)
1037 {
1038     m_dumpBackForwardList = true;
1039     result->setNull();
1040 }
1041
1042 void TestRunner::setDeferMainResourceDataLoad(const CppArgumentList& arguments, CppVariant* result)
1043 {
1044     if (arguments.size() == 1)
1045         m_deferMainResourceDataLoad = cppVariantToBool(arguments[0]);
1046 }
1047
1048 void TestRunner::dumpSelectionRect(const CppArgumentList& arguments, CppVariant* result)
1049 {
1050     m_dumpSelectionRect = true;
1051     result->setNull();
1052 }
1053
1054 void TestRunner::testRepaint(const CppArgumentList&, CppVariant* result)
1055 {
1056     m_testRepaint = true;
1057     result->setNull();
1058 }
1059
1060 void TestRunner::repaintSweepHorizontally(const CppArgumentList&, CppVariant* result)
1061 {
1062     m_sweepHorizontally = true;
1063     result->setNull();
1064 }
1065
1066 void TestRunner::setPrinting(const CppArgumentList& arguments, CppVariant* result)
1067 {
1068     m_isPrinting = true;
1069     result->setNull();
1070 }
1071
1072 void TestRunner::setShouldStayOnPageAfterHandlingBeforeUnload(const CppArgumentList& arguments, CppVariant* result)
1073 {
1074     if (arguments.size() == 1 && arguments[0].isBool())
1075         m_shouldStayOnPageAfterHandlingBeforeUnload = arguments[0].toBoolean();
1076
1077     result->setNull();
1078 }
1079
1080 void TestRunner::setWillSendRequestClearHeader(const CppArgumentList& arguments, CppVariant* result)
1081 {
1082     if (arguments.size() > 0 && arguments[0].isString()) {
1083         string header = arguments[0].toString();
1084         if (!header.empty())
1085             m_httpHeadersToClear.insert(header);
1086     }
1087     result->setNull();
1088 }
1089
1090 void TestRunner::setWillSendRequestReturnsNullOnRedirect(const CppArgumentList& arguments, CppVariant* result)
1091 {
1092     if (arguments.size() > 0 && arguments[0].isBool())
1093         m_shouldBlockRedirects = arguments[0].toBoolean();
1094     result->setNull();
1095 }
1096
1097 void TestRunner::setWillSendRequestReturnsNull(const CppArgumentList& arguments, CppVariant* result)
1098 {
1099     if (arguments.size() > 0 && arguments[0].isBool())
1100         m_willSendRequestShouldReturnNull = arguments[0].toBoolean();
1101     result->setNull();
1102 }
1103
1104 void TestRunner::setTabKeyCyclesThroughElements(const CppArgumentList& arguments, CppVariant* result)
1105 {
1106     if (arguments.size() > 0 && arguments[0].isBool())
1107         m_webView->setTabKeyCyclesThroughElements(arguments[0].toBoolean());
1108     result->setNull();
1109 }
1110
1111 void TestRunner::execCommand(const CppArgumentList& arguments, CppVariant* result)
1112 {
1113     result->setNull();
1114     if (arguments.size() <= 0 || !arguments[0].isString())
1115         return;
1116
1117     std::string command = arguments[0].toString();
1118     std::string value("");
1119     // Ignore the second parameter (which is userInterface)
1120     // since this command emulates a manual action.
1121     if (arguments.size() >= 3 && arguments[2].isString())
1122         value = arguments[2].toString();
1123
1124     // Note: webkit's version does not return the boolean, so neither do we.
1125     m_webView->focusedFrame()->executeCommand(WebString::fromUTF8(command), WebString::fromUTF8(value));
1126 }
1127
1128 void TestRunner::isCommandEnabled(const CppArgumentList& arguments, CppVariant* result)
1129 {
1130     if (arguments.size() <= 0 || !arguments[0].isString()) {
1131         result->setNull();
1132         return;
1133     }
1134
1135     std::string command = arguments[0].toString();
1136     bool rv = m_webView->focusedFrame()->isCommandEnabled(WebString::fromUTF8(command));
1137     result->set(rv);
1138 }
1139
1140 bool TestRunner::elementDoesAutoCompleteForElementWithId(const WebString& elementId)
1141 {
1142     WebFrame* webFrame = m_webView->mainFrame();
1143     if (!webFrame)
1144         return false;
1145
1146     WebElement element = webFrame->document().getElementById(elementId);
1147     if (element.isNull() || !element.hasTagName("input"))
1148         return false;
1149
1150     WebInputElement inputElement = element.to<WebInputElement>();
1151     return inputElement.autoComplete();
1152 }
1153
1154 void TestRunner::elementDoesAutoCompleteForElementWithId(const CppArgumentList& arguments, CppVariant* result)
1155 {
1156     if (arguments.size() != 1 || !arguments[0].isString()) {
1157         result->set(false);
1158         return;
1159     }
1160     WebString elementId = cppVariantToWebString(arguments[0]);
1161     result->set(elementDoesAutoCompleteForElementWithId(elementId));
1162 }
1163
1164 void TestRunner::callShouldCloseOnWebView(const CppArgumentList&, CppVariant* result)
1165 {
1166     result->set(m_webView->dispatchBeforeUnloadEvent());
1167 }
1168
1169 void TestRunner::setDomainRelaxationForbiddenForURLScheme(const CppArgumentList& arguments, CppVariant* result)
1170 {
1171     if (arguments.size() != 2 || !arguments[0].isBool() || !arguments[1].isString())
1172         return;
1173     m_webView->setDomainRelaxationForbidden(cppVariantToBool(arguments[0]), cppVariantToWebString(arguments[1]));
1174 }
1175
1176 void TestRunner::evaluateScriptInIsolatedWorldAndReturnValue(const CppArgumentList& arguments, CppVariant* result)
1177 {
1178     v8::HandleScope scope;
1179     WebVector<v8::Local<v8::Value> > values;
1180     if (arguments.size() >= 2 && arguments[0].isNumber() && arguments[1].isString()) {
1181         WebScriptSource source(cppVariantToWebString(arguments[1]));
1182         // This relies on the iframe focusing itself when it loads. This is a bit
1183         // sketchy, but it seems to be what other tests do.
1184         m_webView->focusedFrame()->executeScriptInIsolatedWorld(arguments[0].toInt32(), &source, 1, 1, &values);
1185     }
1186     result->setNull();
1187     // Since only one script was added, only one result is expected
1188     if (values.size() == 1 && !values[0].IsEmpty()) {
1189         v8::Local<v8::Value> scriptValue = values[0];
1190         // FIXME: There are many more types that can be handled.
1191         if (scriptValue->IsString()) {
1192             v8::String::AsciiValue asciiV8(scriptValue);
1193             result->set(std::string(*asciiV8));
1194         } else if (scriptValue->IsBoolean())
1195             result->set(scriptValue->ToBoolean()->Value());
1196         else if (scriptValue->IsNumber()) {
1197             if (scriptValue->IsInt32())
1198                 result->set(scriptValue->ToInt32()->Value());
1199             else
1200                 result->set(scriptValue->ToNumber()->Value());
1201         } else if (scriptValue->IsNull())
1202             result->setNull();
1203     }
1204 }
1205
1206 void TestRunner::evaluateScriptInIsolatedWorld(const CppArgumentList& arguments, CppVariant* result)
1207 {
1208     if (arguments.size() >= 2 && arguments[0].isNumber() && arguments[1].isString()) {
1209         WebScriptSource source(cppVariantToWebString(arguments[1]));
1210         // This relies on the iframe focusing itself when it loads. This is a bit
1211         // sketchy, but it seems to be what other tests do.
1212         m_webView->focusedFrame()->executeScriptInIsolatedWorld(arguments[0].toInt32(), &source, 1, 1);
1213     }
1214     result->setNull();
1215 }
1216
1217 void TestRunner::setIsolatedWorldSecurityOrigin(const CppArgumentList& arguments, CppVariant* result)
1218 {
1219     result->setNull();
1220
1221     if (arguments.size() != 2 || !arguments[0].isNumber() || !(arguments[1].isString() || arguments[1].isNull()))
1222         return;
1223
1224     WebSecurityOrigin origin;
1225     if (arguments[1].isString())
1226         origin = WebSecurityOrigin::createFromString(cppVariantToWebString(arguments[1]));
1227     m_webView->focusedFrame()->setIsolatedWorldSecurityOrigin(arguments[0].toInt32(), origin);
1228 }
1229
1230 void TestRunner::setIsolatedWorldContentSecurityPolicy(const CppArgumentList& arguments, CppVariant* result)
1231 {
1232     result->setNull();
1233
1234     if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isString())
1235         return;
1236
1237     m_webView->focusedFrame()->setIsolatedWorldContentSecurityPolicy(arguments[0].toInt32(), cppVariantToWebString(arguments[1]));
1238 }
1239
1240 void TestRunner::addOriginAccessWhitelistEntry(const CppArgumentList& arguments, CppVariant* result)
1241 {
1242     result->setNull();
1243
1244     if (arguments.size() != 4 || !arguments[0].isString() || !arguments[1].isString()
1245         || !arguments[2].isString() || !arguments[3].isBool())
1246         return;
1247
1248     WebKit::WebURL url(GURL(arguments[0].toString()));
1249     if (!url.isValid())
1250         return;
1251
1252     WebSecurityPolicy::addOriginAccessWhitelistEntry(
1253         url,
1254         cppVariantToWebString(arguments[1]),
1255         cppVariantToWebString(arguments[2]),
1256         arguments[3].toBoolean());
1257 }
1258
1259 void TestRunner::removeOriginAccessWhitelistEntry(const CppArgumentList& arguments, CppVariant* result)
1260 {
1261     result->setNull();
1262
1263     if (arguments.size() != 4 || !arguments[0].isString() || !arguments[1].isString()
1264         || !arguments[2].isString() || !arguments[3].isBool())
1265         return;
1266
1267     WebKit::WebURL url(GURL(arguments[0].toString()));
1268     if (!url.isValid())
1269         return;
1270
1271     WebSecurityPolicy::removeOriginAccessWhitelistEntry(
1272         url,
1273         cppVariantToWebString(arguments[1]),
1274         cppVariantToWebString(arguments[2]),
1275         arguments[3].toBoolean());
1276 }
1277
1278 void TestRunner::hasCustomPageSizeStyle(const CppArgumentList& arguments, CppVariant* result)
1279 {
1280     result->set(false);
1281     int pageIndex = 0;
1282     if (arguments.size() > 1)
1283         return;
1284     if (arguments.size() == 1)
1285         pageIndex = cppVariantToInt32(arguments[0]);
1286     WebFrame* frame = m_webView->mainFrame();
1287     if (!frame)
1288         return;
1289     result->set(frame->hasCustomPageSizeStyle(pageIndex));
1290 }
1291
1292 void TestRunner::forceRedSelectionColors(const CppArgumentList& arguments, CppVariant* result)
1293 {
1294     result->setNull();
1295     m_webView->setSelectionColors(0xffee0000, 0xff00ee00, 0xff000000, 0xffc0c0c0);
1296 }
1297
1298 void TestRunner::addUserScript(const CppArgumentList& arguments, CppVariant* result)
1299 {
1300     result->setNull();
1301     if (arguments.size() < 3 || !arguments[0].isString() || !arguments[1].isBool() || !arguments[2].isBool())
1302         return;
1303     WebView::addUserScript(
1304         cppVariantToWebString(arguments[0]), WebVector<WebString>(),
1305         arguments[1].toBoolean() ? WebView::UserScriptInjectAtDocumentStart : WebView::UserScriptInjectAtDocumentEnd,
1306         arguments[2].toBoolean() ? WebView::UserContentInjectInAllFrames : WebView::UserContentInjectInTopFrameOnly);
1307 }
1308
1309 void TestRunner::addUserStyleSheet(const CppArgumentList& arguments, CppVariant* result)
1310 {
1311     result->setNull();
1312     if (arguments.size() < 2 || !arguments[0].isString() || !arguments[1].isBool())
1313         return;
1314     WebView::addUserStyleSheet(
1315         cppVariantToWebString(arguments[0]), WebVector<WebString>(),
1316         arguments[1].toBoolean() ? WebView::UserContentInjectInAllFrames : WebView::UserContentInjectInTopFrameOnly,
1317         // Chromium defaults to InjectInSubsequentDocuments, but for compatibility
1318         // with the other ports' DRTs, we use UserStyleInjectInExistingDocuments.
1319         WebView::UserStyleInjectInExistingDocuments);
1320 }
1321
1322 void TestRunner::startSpeechInput(const CppArgumentList& arguments, CppVariant* result)
1323 {
1324     result->setNull();
1325     if (arguments.size() != 1)
1326         return;
1327
1328     WebElement element;
1329     if (!WebBindings::getElement(arguments[0].value.objectValue, &element))
1330         return;
1331
1332     WebInputElement* input = toWebInputElement(&element);
1333     if (!input)
1334         return;
1335
1336     if (!input->isSpeechInputEnabled())
1337         return;
1338
1339     input->startSpeechInput();
1340 }
1341
1342 void TestRunner::markerTextForListItem(const CppArgumentList& args, CppVariant* result)
1343 {
1344     WebElement element;
1345     if (!WebBindings::getElement(args[0].value.objectValue, &element))
1346         result->setNull();
1347     else
1348         result->set(element.document().frame()->markerTextForListItem(element).utf8());
1349 }
1350
1351 void TestRunner::findString(const CppArgumentList& arguments, CppVariant* result)
1352 {
1353     if (arguments.size() < 1 || !arguments[0].isString())
1354         return;
1355
1356     WebFindOptions findOptions;
1357     bool wrapAround = false;
1358     if (arguments.size() >= 2) {
1359         vector<string> optionsArray = arguments[1].toStringVector();
1360         findOptions.matchCase = true;
1361
1362         for (size_t i = 0; i < optionsArray.size(); ++i) {
1363             const std::string& option = optionsArray[i];
1364             // FIXME: Support all the options, so we can run findString.html too.
1365             if (option == "CaseInsensitive")
1366                 findOptions.matchCase = false;
1367             else if (option == "Backwards")
1368                 findOptions.forward = false;
1369             else if (option == "WrapAround")
1370                 wrapAround = true;
1371         }
1372     }
1373
1374     WebFrame* frame = m_webView->mainFrame();
1375     const bool findResult = frame->find(0, cppVariantToWebString(arguments[0]), findOptions, wrapAround, 0);
1376     result->set(findResult);
1377 }
1378
1379 void TestRunner::setValueForUser(const CppArgumentList& arguments, CppVariant* result)
1380 {
1381     result->setNull();
1382     if (arguments.size() != 2)
1383         return;
1384
1385     WebElement element;
1386     if (!WebBindings::getElement(arguments[0].value.objectValue, &element))
1387         return;
1388
1389     WebInputElement* input = toWebInputElement(&element);
1390     if (!input)
1391         return;
1392
1393     input->setValue(cppVariantToWebString(arguments[1]), true);
1394 }
1395
1396 void TestRunner::enableFixedLayoutMode(const CppArgumentList& arguments, CppVariant* result)
1397 {
1398     result->setNull();
1399     if (arguments.size() <  1 || !arguments[0].isBool())
1400         return;
1401     bool enableFixedLayout = arguments[0].toBoolean();
1402     m_webView->enableFixedLayoutMode(enableFixedLayout);
1403 }
1404
1405 void TestRunner::setFixedLayoutSize(const CppArgumentList& arguments, CppVariant* result)
1406 {
1407     result->setNull();
1408     if (arguments.size() <  2 || !arguments[0].isNumber() || !arguments[1].isNumber())
1409         return;
1410     int width = arguments[0].toInt32();
1411     int height = arguments[1].toInt32();
1412     m_webView->setFixedLayoutSize(WebSize(width, height));
1413 }
1414
1415 void TestRunner::selectionAsMarkup(const CppArgumentList& arguments, CppVariant* result)
1416 {
1417     result->set(m_webView->mainFrame()->selectionAsMarkup().utf8());
1418 }
1419
1420 void TestRunner::setTextSubpixelPositioning(const CppArgumentList& arguments, CppVariant* result)
1421 {
1422 #if defined(__linux__) || defined(ANDROID)
1423     // Since FontConfig doesn't provide a variable to control subpixel positioning, we'll fall back
1424     // to setting it globally for all fonts.
1425     if (arguments.size() > 0 && arguments[0].isBool())
1426         WebFontRendering::setSubpixelPositioning(arguments[0].value.boolValue);
1427 #endif
1428     result->setNull();
1429 }
1430
1431 void TestRunner::resetPageVisibility(const CppArgumentList& arguments, CppVariant* result)
1432 {
1433     m_webView->setVisibilityState(WebPageVisibilityStateVisible, true);
1434 }
1435
1436 void TestRunner::setPageVisibility(const CppArgumentList& arguments, CppVariant* result)
1437 {
1438     if (arguments.size() > 0 && arguments[0].isString()) {
1439         string newVisibility = arguments[0].toString();
1440         if (newVisibility == "visible")
1441             m_webView->setVisibilityState(WebPageVisibilityStateVisible, false);
1442         else if (newVisibility == "hidden")
1443             m_webView->setVisibilityState(WebPageVisibilityStateHidden, false);
1444         else if (newVisibility == "prerender")
1445             m_webView->setVisibilityState(WebPageVisibilityStatePrerender, false);
1446         else if (newVisibility == "preview")
1447             m_webView->setVisibilityState(WebPageVisibilityStatePreview, false);
1448     }
1449 }
1450
1451 void TestRunner::setTextDirection(const CppArgumentList& arguments, CppVariant* result)
1452 {
1453     result->setNull();
1454     if (arguments.size() != 1 || !arguments[0].isString())
1455         return;
1456
1457     // Map a direction name to a WebTextDirection value.
1458     std::string directionName = arguments[0].toString();
1459     WebKit::WebTextDirection direction;
1460     if (directionName == "auto")
1461         direction = WebKit::WebTextDirectionDefault;
1462     else if (directionName == "rtl")
1463         direction = WebKit::WebTextDirectionRightToLeft;
1464     else if (directionName == "ltr")
1465         direction = WebKit::WebTextDirectionLeftToRight;
1466     else
1467         return;
1468
1469     m_webView->setTextDirection(direction);
1470 }
1471
1472 void TestRunner::textSurroundingNode(const CppArgumentList& arguments, CppVariant* result)
1473 {
1474     result->setNull();
1475     if (arguments.size() < 4 || !arguments[0].isObject() || !arguments[1].isNumber() || !arguments[2].isNumber() || !arguments[3].isNumber())
1476         return;
1477
1478     WebNode node;
1479     if (!WebBindings::getNode(arguments[0].value.objectValue, &node))
1480         return;
1481
1482     if (node.isNull() || !node.isTextNode())
1483         return;
1484
1485     WebPoint point(arguments[1].toInt32(), arguments[2].toInt32());
1486     unsigned maxLength = arguments[3].toInt32();
1487
1488     WebSurroundingText surroundingText;
1489     surroundingText.initialize(node, point, maxLength);
1490     if (surroundingText.isNull())
1491         return;
1492
1493     result->set(surroundingText.textContent().utf8());
1494 }
1495
1496 void TestRunner::setSmartInsertDeleteEnabled(const CppArgumentList& arguments, CppVariant* result)
1497 {
1498     if (arguments.size() > 0 && arguments[0].isBool())
1499         m_smartInsertDeleteEnabled = arguments[0].value.boolValue;
1500     result->setNull();
1501 }
1502
1503 void TestRunner::setSelectTrailingWhitespaceEnabled(const CppArgumentList& arguments, CppVariant* result)
1504 {
1505     if (arguments.size() > 0 && arguments[0].isBool())
1506         m_selectTrailingWhitespaceEnabled = arguments[0].value.boolValue;
1507     result->setNull();
1508 }
1509
1510 void TestRunner::enableAutoResizeMode(const CppArgumentList& arguments, CppVariant* result)
1511 {
1512     if (arguments.size() != 4) {
1513         result->set(false);
1514         return;
1515     }
1516     int minWidth = cppVariantToInt32(arguments[0]);
1517     int minHeight = cppVariantToInt32(arguments[1]);
1518     WebKit::WebSize minSize(minWidth, minHeight);
1519
1520     int maxWidth = cppVariantToInt32(arguments[2]);
1521     int maxHeight = cppVariantToInt32(arguments[3]);
1522     WebKit::WebSize maxSize(maxWidth, maxHeight);
1523
1524     m_webView->enableAutoResizeMode(minSize, maxSize);
1525     result->set(true);
1526 }
1527
1528 void TestRunner::disableAutoResizeMode(const CppArgumentList& arguments, CppVariant* result)
1529 {
1530     if (arguments.size() !=2) {
1531         result->set(false);
1532         return;
1533     }
1534     int newWidth = cppVariantToInt32(arguments[0]);
1535     int newHeight = cppVariantToInt32(arguments[1]);
1536     WebKit::WebSize newSize(newWidth, newHeight);
1537
1538     m_delegate->setClientWindowRect(WebRect(0, 0, newSize.width, newSize.height));
1539     m_webView->disableAutoResizeMode();
1540     m_webView->resize(newSize);
1541     result->set(true);
1542 }
1543
1544 void TestRunner::setMockDeviceOrientation(const CppArgumentList& arguments, CppVariant* result)
1545 {
1546     result->setNull();
1547     if (arguments.size() < 6 || !arguments[0].isBool() || !arguments[1].isNumber() || !arguments[2].isBool() || !arguments[3].isNumber() || !arguments[4].isBool() || !arguments[5].isNumber())
1548         return;
1549
1550     WebDeviceOrientation orientation;
1551     orientation.setNull(false);
1552     if (arguments[0].toBoolean())
1553         orientation.setAlpha(arguments[1].toDouble());
1554     if (arguments[2].toBoolean())
1555         orientation.setBeta(arguments[3].toDouble());
1556     if (arguments[4].toBoolean())
1557         orientation.setGamma(arguments[5].toDouble());
1558
1559     // Note that we only call setOrientation on the main page's mock since this
1560     // tests require. If necessary, we could get a list of WebViewHosts from th
1561     // call setOrientation on each DeviceOrientationClientMock.
1562     m_proxy->deviceOrientationClientMock()->setOrientation(orientation);
1563 }
1564
1565 void TestRunner::setUserStyleSheetEnabled(const CppArgumentList& arguments, CppVariant* result)
1566 {
1567     if (arguments.size() > 0 && arguments[0].isBool()) {
1568         m_delegate->preferences()->userStyleSheetLocation = arguments[0].value.boolValue ? m_userStyleSheetLocation : WebURL();
1569         m_delegate->applyPreferences();
1570     }
1571     result->setNull();
1572 }
1573
1574 void TestRunner::setUserStyleSheetLocation(const CppArgumentList& arguments, CppVariant* result)
1575 {
1576     if (arguments.size() > 0 && arguments[0].isString()) {
1577         m_userStyleSheetLocation = m_delegate->localFileToDataURL(m_delegate->rewriteLayoutTestsURL(arguments[0].toString()));
1578         m_delegate->preferences()->userStyleSheetLocation = m_userStyleSheetLocation;
1579         m_delegate->applyPreferences();
1580     }
1581     result->setNull();
1582 }
1583
1584 void TestRunner::setAuthorAndUserStylesEnabled(const CppArgumentList& arguments, CppVariant* result)
1585 {
1586     if (arguments.size() > 0 && arguments[0].isBool()) {
1587         m_delegate->preferences()->authorAndUserStylesEnabled = arguments[0].value.boolValue;
1588         m_delegate->applyPreferences();
1589     }
1590     result->setNull();
1591 }
1592
1593 void TestRunner::setPopupBlockingEnabled(const CppArgumentList& arguments, CppVariant* result)
1594 {
1595     if (arguments.size() > 0 && arguments[0].isBool()) {
1596         bool blockPopups = arguments[0].toBoolean();
1597         m_delegate->preferences()->javaScriptCanOpenWindowsAutomatically = !blockPopups;
1598         m_delegate->applyPreferences();
1599     }
1600     result->setNull();
1601 }
1602
1603 void TestRunner::setJavaScriptCanAccessClipboard(const CppArgumentList& arguments, CppVariant* result)
1604 {
1605     if (arguments.size() > 0 && arguments[0].isBool()) {
1606         m_delegate->preferences()->javaScriptCanAccessClipboard = arguments[0].value.boolValue;
1607         m_delegate->applyPreferences();
1608     }
1609     result->setNull();
1610 }
1611
1612 void TestRunner::setXSSAuditorEnabled(const CppArgumentList& arguments, CppVariant* result)
1613 {
1614     if (arguments.size() > 0 && arguments[0].isBool()) {
1615         m_delegate->preferences()->XSSAuditorEnabled = arguments[0].value.boolValue;
1616         m_delegate->applyPreferences();
1617     }
1618     result->setNull();
1619 }
1620
1621 void TestRunner::setAllowUniversalAccessFromFileURLs(const CppArgumentList& arguments, CppVariant* result)
1622 {
1623     if (arguments.size() > 0 && arguments[0].isBool()) {
1624         m_delegate->preferences()->allowUniversalAccessFromFileURLs = arguments[0].value.boolValue;
1625         m_delegate->applyPreferences();
1626     }
1627     result->setNull();
1628 }
1629
1630 void TestRunner::setAllowFileAccessFromFileURLs(const CppArgumentList& arguments, CppVariant* result)
1631 {
1632     if (arguments.size() > 0 && arguments[0].isBool()) {
1633         m_delegate->preferences()->allowFileAccessFromFileURLs = arguments[0].value.boolValue;
1634         m_delegate->applyPreferences();
1635     }
1636     result->setNull();
1637 }
1638
1639 void TestRunner::overridePreference(const CppArgumentList& arguments, CppVariant* result)
1640 {
1641     result->setNull();
1642     if (arguments.size() != 2 || !arguments[0].isString())
1643         return;
1644
1645     string key = arguments[0].toString();
1646     CppVariant value = arguments[1];
1647     WebPreferences* prefs = m_delegate->preferences();
1648     if (key == "WebKitDefaultFontSize")
1649         prefs->defaultFontSize = cppVariantToInt32(value);
1650     else if (key == "WebKitMinimumFontSize")
1651         prefs->minimumFontSize = cppVariantToInt32(value);
1652     else if (key == "WebKitDefaultTextEncodingName")
1653         prefs->defaultTextEncodingName = cppVariantToWebString(value);
1654     else if (key == "WebKitJavaScriptEnabled")
1655         prefs->javaScriptEnabled = cppVariantToBool(value);
1656     else if (key == "WebKitSupportsMultipleWindows")
1657         prefs->supportsMultipleWindows = cppVariantToBool(value);
1658     else if (key == "WebKitDisplayImagesKey")
1659         prefs->loadsImagesAutomatically = cppVariantToBool(value);
1660     else if (key == "WebKitPluginsEnabled")
1661         prefs->pluginsEnabled = cppVariantToBool(value);
1662     else if (key == "WebKitJavaEnabled")
1663         prefs->javaEnabled = cppVariantToBool(value);
1664     else if (key == "WebKitUsesPageCachePreferenceKey")
1665         prefs->usesPageCache = cppVariantToBool(value);
1666     else if (key == "WebKitPageCacheSupportsPluginsPreferenceKey")
1667         prefs->pageCacheSupportsPlugins = cppVariantToBool(value);
1668     else if (key == "WebKitOfflineWebApplicationCacheEnabled")
1669         prefs->offlineWebApplicationCacheEnabled = cppVariantToBool(value);
1670     else if (key == "WebKitTabToLinksPreferenceKey")
1671         prefs->tabsToLinks = cppVariantToBool(value);
1672     else if (key == "WebKitWebGLEnabled")
1673         prefs->experimentalWebGLEnabled = cppVariantToBool(value);
1674     else if (key == "WebKitCSSRegionsEnabled")
1675         prefs->experimentalCSSRegionsEnabled = cppVariantToBool(value);
1676     else if (key == "WebKitCSSGridLayoutEnabled")
1677         prefs->experimentalCSSGridLayoutEnabled = cppVariantToBool(value);
1678     else if (key == "WebKitHyperlinkAuditingEnabled")
1679         prefs->hyperlinkAuditingEnabled = cppVariantToBool(value);
1680     else if (key == "WebKitEnableCaretBrowsing")
1681         prefs->caretBrowsingEnabled = cppVariantToBool(value);
1682     else if (key == "WebKitAllowDisplayingInsecureContent")
1683         prefs->allowDisplayOfInsecureContent = cppVariantToBool(value);
1684     else if (key == "WebKitAllowRunningInsecureContent")
1685         prefs->allowRunningOfInsecureContent = cppVariantToBool(value);
1686     else if (key == "WebKitCSSCustomFilterEnabled")
1687         prefs->cssCustomFilterEnabled = cppVariantToBool(value);
1688     else if (key == "WebKitShouldRespectImageOrientation")
1689         prefs->shouldRespectImageOrientation = cppVariantToBool(value);
1690     else if (key == "WebKitWebAudioEnabled")
1691         WEBKIT_ASSERT(cppVariantToBool(value));
1692     else {
1693         string message("Invalid name for preference: ");
1694         message.append(key);
1695         printErrorMessage(message);
1696     }
1697     m_delegate->applyPreferences();
1698 }
1699
1700 void TestRunner::setPluginsEnabled(const CppArgumentList& arguments, CppVariant* result)
1701 {
1702     if (arguments.size() > 0 && arguments[0].isBool()) {
1703         m_delegate->preferences()->pluginsEnabled = arguments[0].toBoolean();
1704         m_delegate->applyPreferences();
1705     }
1706     result->setNull();
1707 }
1708
1709 void TestRunner::setAsynchronousSpellCheckingEnabled(const CppArgumentList& arguments, CppVariant* result)
1710 {
1711     if (arguments.size() > 0 && arguments[0].isBool()) {
1712         m_delegate->preferences()->asynchronousSpellCheckingEnabled = cppVariantToBool(arguments[0]);
1713         m_delegate->applyPreferences();
1714     }
1715     result->setNull();
1716 }
1717
1718 void TestRunner::setTouchDragDropEnabled(const CppArgumentList& arguments, CppVariant* result)
1719 {
1720     if (arguments.size() > 0 && arguments[0].isBool()) {
1721         m_delegate->preferences()->touchDragDropEnabled = arguments[0].toBoolean();
1722         m_delegate->applyPreferences();
1723     }
1724     result->setNull();
1725 }
1726
1727 void TestRunner::showWebInspector(const CppArgumentList&, CppVariant* result)
1728 {
1729     showDevTools();
1730     result->setNull();
1731 }
1732
1733 void TestRunner::closeWebInspector(const CppArgumentList& args, CppVariant* result)
1734 {
1735     m_delegate->closeDevTools();
1736     result->setNull();
1737 }
1738
1739 void TestRunner::evaluateInWebInspector(const CppArgumentList& arguments, CppVariant* result)
1740 {
1741     result->setNull();
1742     if (arguments.size() < 2 || !arguments[0].isNumber() || !arguments[1].isString())
1743         return;
1744     m_delegate->evaluateInWebInspector(arguments[0].toInt32(), arguments[1].toString());
1745 }
1746
1747 void TestRunner::clearAllDatabases(const CppArgumentList& arguments, CppVariant* result)
1748 {
1749     result->setNull();
1750     m_delegate->clearAllDatabases();
1751 }
1752
1753 void TestRunner::setDatabaseQuota(const CppArgumentList& arguments, CppVariant* result)
1754 {
1755     result->setNull();
1756     if ((arguments.size() >= 1) && arguments[0].isNumber())
1757         m_delegate->setDatabaseQuota(arguments[0].toInt32());
1758 }
1759
1760 void TestRunner::setAlwaysAcceptCookies(const CppArgumentList& arguments, CppVariant* result)
1761 {
1762     if (arguments.size() > 0)
1763         m_delegate->setAcceptAllCookies(cppVariantToBool(arguments[0]));
1764     result->setNull();
1765 }
1766
1767 void TestRunner::setWindowIsKey(const CppArgumentList& arguments, CppVariant* result)
1768 {
1769     if (arguments.size() > 0 && arguments[0].isBool())
1770         m_delegate->setFocus(arguments[0].value.boolValue);
1771     result->setNull();
1772 }
1773
1774 void TestRunner::pathToLocalResource(const CppArgumentList& arguments, CppVariant* result)
1775 {
1776     result->setNull();
1777     if (arguments.size() <= 0 || !arguments[0].isString())
1778         return;
1779
1780     result->set(m_delegate->pathToLocalResource(arguments[0].toString()));
1781 }
1782
1783 void TestRunner::setBackingScaleFactor(const CppArgumentList& arguments, CppVariant* result)
1784 {
1785     if (arguments.size() < 2 || !arguments[0].isNumber() || !arguments[1].isObject())
1786         return;
1787
1788     float value = arguments[0].value.doubleValue;
1789     m_delegate->setDeviceScaleFactor(value);
1790     m_proxy->discardBackingStore();
1791
1792     auto_ptr<CppVariant> callbackArguments(new CppVariant());
1793     callbackArguments->set(arguments[1]);
1794     result->setNull();
1795     m_delegate->postTask(new InvokeCallbackTask(this, callbackArguments));
1796 }
1797
1798 void TestRunner::setPOSIXLocale(const CppArgumentList& arguments, CppVariant* result)
1799 {
1800     result->setNull();
1801     if (arguments.size() == 1 && arguments[0].isString())
1802         m_delegate->setLocale(arguments[0].toString());
1803 }
1804
1805 void TestRunner::numberOfPendingGeolocationPermissionRequests(const CppArgumentList& arguments, CppVariant* result)
1806 {
1807     result->set(m_proxy->geolocationClientMock()->numberOfPendingPermissionRequests());
1808 }
1809
1810 // FIXME: For greater test flexibility, we should be able to set each page's geolocation mock individually.
1811 // https://bugs.webkit.org/show_bug.cgi?id=52368
1812 void TestRunner::setGeolocationPermission(const CppArgumentList& arguments, CppVariant* result)
1813 {
1814     result->setNull();
1815     if (arguments.size() < 1 || !arguments[0].isBool())
1816         return;
1817     const vector<WebTestProxyBase*>& windowList = m_testInterfaces->windowList();
1818     for (unsigned i = 0; i < windowList.size(); ++i)
1819         windowList.at(i)->geolocationClientMock()->setPermission(arguments[0].toBoolean());
1820 }
1821
1822 void TestRunner::setMockGeolocationPosition(const CppArgumentList& arguments, CppVariant* result)
1823 {
1824     result->setNull();
1825     if (arguments.size() < 3 || !arguments[0].isNumber() || !arguments[1].isNumber() || !arguments[2].isNumber())
1826         return;
1827     const vector<WebTestProxyBase*>& windowList = m_testInterfaces->windowList();
1828     for (unsigned i = 0; i < windowList.size(); ++i)
1829         windowList.at(i)->geolocationClientMock()->setPosition(arguments[0].toDouble(), arguments[1].toDouble(), arguments[2].toDouble());
1830 }
1831
1832 void TestRunner::setMockGeolocationPositionUnavailableError(const CppArgumentList& arguments, CppVariant* result)
1833 {
1834     result->setNull();
1835     if (arguments.size() != 1 || !arguments[0].isString())
1836         return;
1837     const vector<WebTestProxyBase*>& windowList = m_testInterfaces->windowList();
1838     for (unsigned i = 0; i < windowList.size(); ++i)
1839         windowList.at(i)->geolocationClientMock()->setPositionUnavailableError(WebString::fromUTF8(arguments[0].toString()));
1840 }
1841
1842 #if ENABLE_NOTIFICATIONS
1843 void TestRunner::grantWebNotificationPermission(const CppArgumentList& arguments, CppVariant* result)
1844 {
1845     if (arguments.size() != 1 || !arguments[0].isString()) {
1846         result->set(false);
1847         return;
1848     }
1849     m_notificationPresenter->grantPermission(WebString::fromUTF8(arguments[0].toString()));
1850     result->set(true);
1851 }
1852
1853 void TestRunner::simulateLegacyWebNotificationClick(const CppArgumentList& arguments, CppVariant* result)
1854 {
1855     if (arguments.size() != 1 || !arguments[0].isString()) {
1856         result->set(false);
1857         return;
1858     }
1859     result->set(m_notificationPresenter->simulateClick(WebString::fromUTF8(arguments[0].toString())));
1860 }
1861 #endif
1862
1863 void TestRunner::addMockSpeechInputResult(const CppArgumentList& arguments, CppVariant* result)
1864 {
1865     result->setNull();
1866     if (arguments.size() < 3 || !arguments[0].isString() || !arguments[1].isNumber() || !arguments[2].isString())
1867         return;
1868
1869 #if ENABLE_INPUT_SPEECH
1870     m_proxy->speechInputControllerMock()->addMockRecognitionResult(WebString::fromUTF8(arguments[0].toString()), arguments[1].toDouble(), WebString::fromUTF8(arguments[2].toString()));
1871 #endif
1872 }
1873
1874 void TestRunner::setMockSpeechInputDumpRect(const CppArgumentList& arguments, CppVariant* result)
1875 {
1876     result->setNull();
1877     if (arguments.size() < 1 || !arguments[0].isBool())
1878         return;
1879
1880 #if ENABLE_INPUT_SPEECH
1881     m_proxy->speechInputControllerMock()->setDumpRect(arguments[0].toBoolean());
1882 #endif
1883 }
1884
1885 void TestRunner::addMockSpeechRecognitionResult(const CppArgumentList& arguments, CppVariant* result)
1886 {
1887     result->setNull();
1888     if (arguments.size() < 2 || !arguments[0].isString() || !arguments[1].isNumber())
1889         return;
1890
1891     m_proxy->speechRecognizerMock()->addMockResult(WebString::fromUTF8(arguments[0].toString()), arguments[1].toDouble());
1892 }
1893
1894 void TestRunner::setMockSpeechRecognitionError(const CppArgumentList& arguments, CppVariant* result)
1895 {
1896     result->setNull();
1897     if (arguments.size() != 2 || !arguments[0].isString() || !arguments[1].isString())
1898         return;
1899
1900     m_proxy->speechRecognizerMock()->setError(WebString::fromUTF8(arguments[0].toString()), WebString::fromUTF8(arguments[1].toString()));
1901 }
1902
1903 void TestRunner::wasMockSpeechRecognitionAborted(const CppArgumentList&, CppVariant* result)
1904 {
1905     result->set(m_proxy->speechRecognizerMock()->wasAborted());
1906 }
1907
1908 void TestRunner::display(const CppArgumentList& arguments, CppVariant* result)
1909 {
1910     m_proxy->display();
1911     result->setNull();
1912 }
1913
1914 void TestRunner::displayInvalidatedRegion(const CppArgumentList& arguments, CppVariant* result)
1915 {
1916     m_proxy->displayInvalidatedRegion();
1917     result->setNull();
1918 }
1919
1920 void TestRunner::dumpEditingCallbacks(const CppArgumentList&, CppVariant* result)
1921 {
1922     m_dumpEditingCallbacks = true;
1923     result->setNull();
1924 }
1925
1926 void TestRunner::dumpAsText(const CppArgumentList& arguments, CppVariant* result)
1927 {
1928     m_dumpAsText = true;
1929     m_generatePixelResults = false;
1930
1931     // Optional paramater, describing whether it's allowed to dump pixel results in dumpAsText mode.
1932     if (arguments.size() > 0 && arguments[0].isBool())
1933         m_generatePixelResults = arguments[0].value.boolValue;
1934
1935     result->setNull();
1936 }
1937
1938 void TestRunner::dumpChildFrameScrollPositions(const CppArgumentList&, CppVariant* result)
1939 {
1940     m_dumpChildFrameScrollPositions = true;
1941     result->setNull();
1942 }
1943
1944 void TestRunner::dumpChildFramesAsText(const CppArgumentList&, CppVariant* result)
1945 {
1946     m_dumpChildFramesAsText = true;
1947     result->setNull();
1948 }
1949
1950 void TestRunner::setAudioData(const CppArgumentList& arguments, CppVariant* result)
1951 {
1952     result->setNull();
1953
1954     if (arguments.size() < 1 || !arguments[0].isObject())
1955         return;
1956
1957     // Check that passed-in object is, in fact, an ArrayBufferView.
1958     NPObject* npobject = NPVARIANT_TO_OBJECT(arguments[0]);
1959     if (!npobject)
1960         return;
1961     if (!WebBindings::getArrayBufferView(npobject, &m_audioData))
1962         return;
1963
1964     m_dumpAsAudio = true;
1965 }
1966
1967 void TestRunner::dumpFrameLoadCallbacks(const CppArgumentList&, CppVariant* result)
1968 {
1969     m_dumpFrameLoadCallbacks = true;
1970     result->setNull();
1971 }
1972
1973 void TestRunner::dumpUserGestureInFrameLoadCallbacks(const CppArgumentList&, CppVariant* result)
1974 {
1975     m_dumpUserGestureInFrameLoadCallbacks = true;
1976     result->setNull();
1977 }
1978
1979 void TestRunner::setStopProvisionalFrameLoads(const CppArgumentList&, CppVariant* result)
1980 {
1981     result->setNull();
1982     m_stopProvisionalFrameLoads = true;
1983 }
1984
1985 void TestRunner::dumpTitleChanges(const CppArgumentList&, CppVariant* result)
1986 {
1987     m_dumpTitleChanges = true;
1988     result->setNull();
1989 }
1990
1991 void TestRunner::dumpCreateView(const CppArgumentList&, CppVariant* result)
1992 {
1993     m_dumpCreateView = true;
1994     result->setNull();
1995 }
1996
1997 void TestRunner::setCanOpenWindows(const CppArgumentList&, CppVariant* result)
1998 {
1999     m_canOpenWindows = true;
2000     result->setNull();
2001 }
2002
2003 void TestRunner::dumpResourceLoadCallbacks(const CppArgumentList&, CppVariant* result)
2004 {
2005     m_dumpResourceLoadCallbacks = true;
2006     result->setNull();
2007 }
2008
2009 void TestRunner::dumpResourceRequestCallbacks(const CppArgumentList&, CppVariant* result)
2010 {
2011     m_dumpResourceRequestCallbacks = true;
2012     result->setNull();
2013 }
2014
2015 void TestRunner::dumpResourceResponseMIMETypes(const CppArgumentList&, CppVariant* result)
2016 {
2017     m_dumpResourceResponseMIMETypes = true;
2018     result->setNull();
2019 }
2020
2021 // Need these conversions because the format of the value for booleans
2022 // may vary - for example, on mac "1" and "0" are used for boolean.
2023 bool TestRunner::cppVariantToBool(const CppVariant& value)
2024 {
2025     if (value.isBool())
2026         return value.toBoolean();
2027     if (value.isNumber())
2028         return value.toInt32();
2029     if (value.isString()) {
2030         string valueString = value.toString();
2031         if (valueString == "true" || valueString == "1")
2032             return true;
2033         if (valueString == "false" || valueString == "0")
2034             return false;
2035     }
2036     printErrorMessage("Invalid value. Expected boolean value.");
2037     return false;
2038 }
2039
2040 int32_t TestRunner::cppVariantToInt32(const CppVariant& value)
2041 {
2042     if (value.isNumber())
2043         return value.toInt32();
2044     if (value.isString()) {
2045         string stringSource = value.toString();
2046         const char* source = stringSource.data();
2047         char* end;
2048         long number = strtol(source, &end, 10);
2049         if (end == source + stringSource.length() && number >= numeric_limits<int32_t>::min() && number <= numeric_limits<int32_t>::max())
2050             return static_cast<int32_t>(number);
2051     }
2052     printErrorMessage("Invalid value for preference. Expected integer value.");
2053     return 0;
2054 }
2055
2056 WebString TestRunner::cppVariantToWebString(const CppVariant& value)
2057 {
2058     if (!value.isString()) {
2059         printErrorMessage("Invalid value for preference. Expected string value.");
2060         return WebString();
2061     }
2062     return WebString::fromUTF8(value.toString());
2063 }
2064
2065 void TestRunner::printErrorMessage(const string& text)
2066 {
2067     m_delegate->printMessage(string("CONSOLE MESSAGE: ") + text + "\n");
2068 }
2069
2070 void TestRunner::fallbackMethod(const CppArgumentList&, CppVariant* result)
2071 {
2072     printErrorMessage("JavaScript ERROR: unknown method called on TestRunner");
2073     result->setNull();
2074 }
2075
2076 void TestRunner::notImplemented(const CppArgumentList&, CppVariant* result)
2077 {
2078     result->setNull();
2079 }
2080
2081 void TestRunner::didAcquirePointerLock(const CppArgumentList&, CppVariant* result)
2082 {
2083     didAcquirePointerLockInternal();
2084     result->setNull();
2085 }
2086
2087 void TestRunner::didNotAcquirePointerLock(const CppArgumentList&, CppVariant* result)
2088 {
2089     didNotAcquirePointerLockInternal();
2090     result->setNull();
2091 }
2092
2093 void TestRunner::didLosePointerLock(const CppArgumentList&, CppVariant* result)
2094 {
2095     didLosePointerLockInternal();
2096     result->setNull();
2097 }
2098
2099 void TestRunner::setPointerLockWillRespondAsynchronously(const CppArgumentList&, CppVariant* result)
2100 {
2101     m_pointerLockPlannedResult = PointerLockWillRespondAsync;
2102     result->setNull();
2103 }
2104
2105 void TestRunner::setPointerLockWillFailSynchronously(const CppArgumentList&, CppVariant* result)
2106 {
2107     m_pointerLockPlannedResult = PointerLockWillFailSync;
2108     result->setNull();
2109 }
2110
2111 }