1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * Copyright (C) 2010 Pawel Hajdan (phajdan.jr (at) 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 68 using namespace WebCore; 69 using namespace WebKit; 70 using namespace std; 71 72 LayoutTestController::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 220 LayoutTestController::~LayoutTestController() 221 { 222 } 223 224 LayoutTestController::WorkQueue::~WorkQueue() 225 { 226 reset(); 227 } 228 229 void 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 241 void 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 256 void LayoutTestController::WorkQueue::reset() 257 { 258 m_frozen = false; 259 while (!m_queue.isEmpty()) { 260 delete m_queue.takeFirst(); 261 } 262 } 263 264 void LayoutTestController::WorkQueue::addWork(WorkItem* work) 265 { 266 if (m_frozen) { 267 delete work; 268 return; 269 } 270 m_queue.append(work); 271 } 272 273 void 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 285 void LayoutTestController::dumpDatabaseCallbacks(const CppArgumentList&, CppVariant* result) 286 { 287 // Do nothing; we don't use this flag anywhere for now 288 result->setNull(); 289 } 290 291 void LayoutTestController::dumpEditingCallbacks(const CppArgumentList&, CppVariant* result) 292 { 293 m_dumpEditingCallbacks = true; 294 result->setNull(); 295 } 296 297 void LayoutTestController::dumpBackForwardList(const CppArgumentList&, CppVariant* result) 298 { 299 m_dumpBackForwardList = true; 300 result->setNull(); 301 } 302 303 void LayoutTestController::dumpFrameLoadCallbacks(const CppArgumentList&, CppVariant* result) 304 { 305 m_dumpFrameLoadCallbacks = true; 306 result->setNull(); 307 } 308 309 void LayoutTestController::dumpUserGestureInFrameLoadCallbacks(const CppArgumentList&, CppVariant* result) 310 { 311 m_dumpUserGestureInFrameLoadCallbacks = true; 312 result->setNull(); 313 } 314 315 void LayoutTestController::dumpResourceLoadCallbacks(const CppArgumentList&, CppVariant* result) 316 { 317 m_dumpResourceLoadCallbacks = true; 318 result->setNull(); 319 } 320 321 void LayoutTestController::dumpResourceResponseMIMETypes(const CppArgumentList&, CppVariant* result) 322 { 323 m_dumpResourceResponseMIMETypes = true; 324 result->setNull(); 325 } 326 327 void LayoutTestController::dumpChildFrameScrollPositions(const CppArgumentList&, CppVariant* result) 328 { 329 m_dumpChildFrameScrollPositions = true; 330 result->setNull(); 331 } 332 333 void LayoutTestController::dumpChildFramesAsText(const CppArgumentList&, CppVariant* result) 334 { 335 m_dumpChildFramesAsText = true; 336 result->setNull(); 337 } 338 339 void LayoutTestController::dumpWindowStatusChanges(const CppArgumentList&, CppVariant* result) 340 { 341 m_dumpWindowStatusChanges = true; 342 result->setNull(); 343 } 344 345 void LayoutTestController::dumpTitleChanges(const CppArgumentList&, CppVariant* result) 346 { 347 m_dumpTitleChanges = true; 348 result->setNull(); 349 } 350 351 void 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 358 void 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 366 void 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 375 void 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 386 class WorkItemBackForward : public LayoutTestController::WorkItem { 387 public: 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 } 394 private: 395 int m_distance; 396 }; 397 398 void 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 405 void 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 412 class WorkItemReload : public LayoutTestController::WorkItem { 413 public: 414 bool run(TestShell* shell) 415 { 416 shell->reload(); 417 return true; 418 } 419 }; 420 421 void LayoutTestController::queueReload(const CppArgumentList&, CppVariant* result) 422 { 423 m_workQueue.addWork(new WorkItemReload); 424 result->setNull(); 425 } 426 427 class WorkItemLoadingScript : public LayoutTestController::WorkItem { 428 public: 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 } 435 private: 436 string m_script; 437 }; 438 439 class WorkItemNonLoadingScript : public LayoutTestController::WorkItem { 440 public: 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 } 447 private: 448 string m_script; 449 }; 450 451 void 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 458 void 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 465 class WorkItemLoad : public LayoutTestController::WorkItem { 466 public: 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 } 475 private: 476 WebURL m_url; 477 WebString m_target; 478 }; 479 480 void 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 496 class WorkItemLoadHTMLString : public LayoutTestController::WorkItem { 497 public: 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 } 511 private: 512 std::string m_html; 513 WebURL m_baseURL; 514 WebURL m_unreachableURL; 515 }; 516 517 void 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 532 void 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 542 void 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 596 void 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 607 void LayoutTestController::policyDelegateDone() 608 { 609 ASSERT(m_waitUntilDone); 610 m_shell->testFinished(); 611 m_waitUntilDone = false; 612 } 613 614 void LayoutTestController::setCanOpenWindows(const CppArgumentList&, CppVariant* result) 615 { 616 m_canOpenWindows = true; 617 result->setNull(); 618 } 619 620 void 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 627 void LayoutTestController::windowCount(const CppArgumentList&, CppVariant* result) 628 { 629 result->set(static_cast<int>(m_shell->windowCount())); 630 } 631 632 void 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 639 void 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 646 void 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 653 void 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 675 void LayoutTestController::showWebInspector(const CppArgumentList&, CppVariant* result) 676 { 677 m_shell->showDevTools(); 678 result->setNull(); 679 } 680 681 void LayoutTestController::closeWebInspector(const CppArgumentList& args, CppVariant* result) 682 { 683 m_shell->closeDevTools(); 684 result->setNull(); 685 } 686 687 void 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 694 void 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 703 void 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 714 void 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 723 void 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 740 void 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 752 void 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 762 void LayoutTestController::setUseDashboardCompatibilityMode(const CppArgumentList&, CppVariant* result) 763 { 764 // We have no need to support Dashboard Compatibility Mode (mac-only) 765 result->setNull(); 766 } 767 768 void LayoutTestController::clearAllApplicationCaches(const CppArgumentList&, CppVariant* result) 769 { 770 // FIXME: Implement to support application cache quotas. 771 result->setNull(); 772 } 773 774 void LayoutTestController::clearApplicationCacheForOrigin(const CppArgumentList&, CppVariant* result) 775 { 776 // FIXME: Implement to support deleting all application cache for an origin. 777 result->setNull(); 778 } 779 780 void LayoutTestController::setApplicationCacheOriginQuota(const CppArgumentList&, CppVariant* result) 781 { 782 // FIXME: Implement to support application cache quotas. 783 result->setNull(); 784 } 785 786 void LayoutTestController::originsWithApplicationCache(const CppArgumentList&, CppVariant* result) 787 { 788 // FIXME: Implement to support getting origins that have application caches. 789 result->setNull(); 790 } 791 792 void 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 799 void 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 811 void LayoutTestController::waitForPolicyDelegate(const CppArgumentList&, CppVariant* result) 812 { 813 m_shell->webViewHost()->waitForPolicyDelegate(); 814 m_waitUntilDone = true; 815 result->setNull(); 816 } 817 818 void 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 828 void 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 835 void 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 842 void 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 880 void LayoutTestController::addFileToPasteboardOnDrag(const CppArgumentList&, CppVariant* result) 881 { 882 result->setNull(); 883 m_shouldAddFileToPasteboard = true; 884 } 885 886 void LayoutTestController::setStopProvisionalFrameLoads(const CppArgumentList&, CppVariant* result) 887 { 888 result->setNull(); 889 m_stopProvisionalFrameLoads = true; 890 } 891 892 void 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 899 void 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 906 bool 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 922 bool 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 938 bool 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 952 int 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 965 void 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 978 void 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 991 void 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 1002 void 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 1013 void 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 1023 void LayoutTestController::numberOfActiveAnimations(const CppArgumentList&, CppVariant* result) 1024 { 1025 result->set(numberOfActiveAnimations()); 1026 } 1027 1028 void LayoutTestController::suspendAnimations(const CppArgumentList&, CppVariant* result) 1029 { 1030 suspendAnimations(); 1031 result->setNull(); 1032 } 1033 1034 void LayoutTestController::resumeAnimations(const CppArgumentList&, CppVariant* result) 1035 { 1036 resumeAnimations(); 1037 result->setNull(); 1038 } 1039 1040 void 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 1053 void LayoutTestController::disableImageLoading(const CppArgumentList&, CppVariant* result) 1054 { 1055 m_shell->preferences()->loadsImagesAutomatically = false; 1056 m_shell->applyPreferences(); 1057 result->setNull(); 1058 } 1059 1060 void LayoutTestController::setIconDatabaseEnabled(const CppArgumentList&, CppVariant* result) 1061 { 1062 // We don't use the WebKit icon database. 1063 result->setNull(); 1064 } 1065 1066 void LayoutTestController::callShouldCloseOnWebView(const CppArgumentList&, CppVariant* result) 1067 { 1068 result->set(m_shell->webView()->dispatchBeforeUnloadEvent()); 1069 } 1070 1071 void 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 1081 void 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 1093 void 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 1100 void 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 1110 void LayoutTestController::dumpAsWebArchive(const CppArgumentList& arguments, CppVariant* result) 1111 { 1112 result->setNull(); 1113 } 1114 1115 void LayoutTestController::setMainFrameIsFirstResponder(const CppArgumentList& arguments, CppVariant* result) 1116 { 1117 result->setNull(); 1118 } 1119 1120 void LayoutTestController::dumpSelectionRect(const CppArgumentList& arguments, CppVariant* result) 1121 { 1122 m_dumpSelectionRect = true; 1123 result->setNull(); 1124 } 1125 1126 void 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 1137 void 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 1145 void LayoutTestController::testRepaint(const CppArgumentList&, CppVariant* result) 1146 { 1147 m_testRepaint = true; 1148 result->setNull(); 1149 } 1150 1151 void LayoutTestController::repaintSweepHorizontally(const CppArgumentList&, CppVariant* result) 1152 { 1153 m_sweepHorizontally = true; 1154 result->setNull(); 1155 } 1156 1157 void LayoutTestController::clearBackForwardList(const CppArgumentList& arguments, CppVariant* result) 1158 { 1159 result->setNull(); 1160 } 1161 1162 void LayoutTestController::keepWebHistory(const CppArgumentList& arguments, CppVariant* result) 1163 { 1164 result->setNull(); 1165 } 1166 1167 void LayoutTestController::storeWebScriptObject(const CppArgumentList& arguments, CppVariant* result) 1168 { 1169 result->setNull(); 1170 } 1171 1172 void LayoutTestController::accessStoredWebScriptObject(const CppArgumentList& arguments, CppVariant* result) 1173 { 1174 result->setNull(); 1175 } 1176 1177 void LayoutTestController::objCClassNameOf(const CppArgumentList& arguments, CppVariant* result) 1178 { 1179 result->setNull(); 1180 } 1181 1182 void LayoutTestController::addDisallowedURL(const CppArgumentList& arguments, CppVariant* result) 1183 { 1184 result->setNull(); 1185 } 1186 1187 void LayoutTestController::setCallCloseOnWebViews(const CppArgumentList& arguments, CppVariant* result) 1188 { 1189 result->setNull(); 1190 } 1191 1192 void LayoutTestController::setPrivateBrowsingEnabled(const CppArgumentList& arguments, CppVariant* result) 1193 { 1194 result->setNull(); 1195 } 1196 1197 void 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 1206 void 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 1215 void 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 1226 void 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 1235 void 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. 1246 bool 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 1263 int32_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 1279 WebString 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 1288 void 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 1365 void LayoutTestController::fallbackMethod(const CppArgumentList&, CppVariant* result) 1366 { 1367 printf("CONSOLE MESSAGE: JavaScript ERROR: unknown method called on LayoutTestController\n"); 1368 result->setNull(); 1369 } 1370 1371 void 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 1390 void 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 1409 void LayoutTestController::clearAllDatabases(const CppArgumentList& arguments, CppVariant* result) 1410 { 1411 result->setNull(); 1412 webkit_support::ClearAllDatabases(); 1413 } 1414 1415 void 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 1422 void 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 1429 void 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 1443 static 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 1468 void 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 1486 void 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 1503 void 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 1513 void LayoutTestController::logErrorToConsole(const std::string& text) 1514 { 1515 m_shell->webViewHost()->didAddMessageToConsole( 1516 WebConsoleMessage(WebConsoleMessage::LevelError, WebString::fromUTF8(text)), 1517 WebString(), 0); 1518 } 1519 1520 void 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 1528 void 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 1536 void 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 1547 void 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 1560 void 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 1576 void 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 1591 void 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 1601 void 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 1611 void 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 1621 void LayoutTestController::abortModal(const CppArgumentList& arguments, CppVariant* result) 1622 { 1623 result->setNull(); 1624 } 1625 1626 void 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 1635 void LayoutTestController::layerTreeAsText(const CppArgumentList& args, CppVariant* result) 1636 { 1637 result->set(m_shell->webView()->mainFrame()->layerTreeAsText(m_showDebugLayerTree).utf8()); 1638 } 1639 1640 void 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 1649 void 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 1656 void 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 1664 void 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 1681 void 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 1698 void LayoutTestController::deleteAllLocalStorage(const CppArgumentList& arguments, CppVariant*) 1699 { 1700 // Not Implemented 1701 } 1702 1703 void LayoutTestController::originsWithLocalStorage(const CppArgumentList& arguments, CppVariant*) 1704 { 1705 // Not Implemented 1706 } 1707 1708 void LayoutTestController::deleteLocalStorageForOrigin(const CppArgumentList& arguments, CppVariant*) 1709 { 1710 // Not Implemented 1711 } 1712 1713 void LayoutTestController::observeStorageTrackerNotifications(const CppArgumentList&, CppVariant*) 1714 { 1715 // Not Implemented 1716 } 1717 1718 void LayoutTestController::syncLocalStorage(const CppArgumentList&, CppVariant*) 1719 { 1720 // Not Implemented 1721 } 1722 1723 void 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