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