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