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