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