1 /* 2 * Copyright (C) 2007 Apple Inc. All rights reserved. 3 * Copyright (C) 2007 Eric Seidel <eric (at) webkit.org> 4 * Copyright (C) 2008 Nuanti Ltd. 5 * Copyright (C) 2009 Jan Michael Alonzo <jmalonzo (at) gmail.com> 6 * Copyright (C) 2009,2011 Collabora Ltd. 7 * Copyright (C) 2010 Joone Hur <joone (at) kldp.org> 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 19 * its contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 23 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 26 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "config.h" 35 #include "LayoutTestController.h" 36 37 #include "DumpRenderTree.h" 38 #include "WebCoreSupport/DumpRenderTreeSupportGtk.h" 39 #include "WorkQueue.h" 40 #include "WorkQueueItem.h" 41 #include <JavaScriptCore/JSRetainPtr.h> 42 #include <JavaScriptCore/JSStringRef.h> 43 #include <cstring> 44 #include <iostream> 45 #include <sstream> 46 #include <stdio.h> 47 #include <glib.h> 48 #include <libsoup/soup.h> 49 #include <webkit/webkit.h> 50 #include <wtf/gobject/GOwnPtr.h> 51 52 extern "C" { 53 void webkit_web_inspector_execute_script(WebKitWebInspector* inspector, long callId, const gchar* script); 54 } 55 56 LayoutTestController::~LayoutTestController() 57 { 58 // FIXME: implement 59 } 60 61 void LayoutTestController::addDisallowedURL(JSStringRef url) 62 { 63 // FIXME: implement 64 } 65 66 void LayoutTestController::clearBackForwardList() 67 { 68 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); 69 WebKitWebBackForwardList* list = webkit_web_view_get_back_forward_list(webView); 70 WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_current_item(list); 71 g_object_ref(item); 72 73 // We clear the history by setting the back/forward list's capacity to 0 74 // then restoring it back and adding back the current item. 75 gint limit = webkit_web_back_forward_list_get_limit(list); 76 webkit_web_back_forward_list_set_limit(list, 0); 77 webkit_web_back_forward_list_set_limit(list, limit); 78 webkit_web_back_forward_list_add_item(list, item); 79 webkit_web_back_forward_list_go_to_item(list, item); 80 g_object_unref(item); 81 } 82 83 JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name) 84 { 85 // FIXME: implement 86 return 0; 87 } 88 89 JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name) 90 { 91 // FIXME: implement 92 return 0; 93 } 94 95 void LayoutTestController::dispatchPendingLoadRequests() 96 { 97 // FIXME: Implement for testing fix for 6727495 98 } 99 100 void LayoutTestController::display() 101 { 102 displayWebView(); 103 } 104 105 JSRetainPtr<JSStringRef> LayoutTestController::counterValueForElementById(JSStringRef id) 106 { 107 gchar* idGChar = JSStringCopyUTF8CString(id); 108 CString counterValueGChar = DumpRenderTreeSupportGtk::counterValueForElementById(mainFrame, idGChar); 109 g_free(idGChar); 110 if (counterValueGChar.isNull()) 111 return 0; 112 JSRetainPtr<JSStringRef> counterValue(Adopt, JSStringCreateWithUTF8CString(counterValueGChar.data())); 113 return counterValue; 114 } 115 116 void LayoutTestController::keepWebHistory() 117 { 118 // FIXME: implement 119 } 120 121 JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef value) 122 { 123 // FIXME: Implement this. 124 return JSValueMakeUndefined(context); 125 } 126 127 JSValueRef LayoutTestController::nodesFromRect(JSContextRef context, JSValueRef value, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping) 128 { 129 return DumpRenderTreeSupportGtk::nodesFromRect(context, value, x, y, top, right, bottom, left, ignoreClipping); 130 } 131 132 JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const 133 { 134 // FIXME: implement 135 JSRetainPtr<JSStringRef> string(Adopt, JSStringCreateWithUTF8CString("")); 136 return string; 137 } 138 139 int LayoutTestController::pageNumberForElementById(JSStringRef id, float pageWidth, float pageHeight) 140 { 141 gchar* idGChar = JSStringCopyUTF8CString(id); 142 int pageNumber = DumpRenderTreeSupportGtk::pageNumberForElementById(mainFrame, idGChar, pageWidth, pageHeight); 143 g_free(idGChar); 144 return pageNumber; 145 } 146 147 int LayoutTestController::numberOfPages(float pageWidth, float pageHeight) 148 { 149 return DumpRenderTreeSupportGtk::numberOfPagesForFrame(mainFrame, pageWidth, pageHeight); 150 } 151 152 JSRetainPtr<JSStringRef> LayoutTestController::pageProperty(const char* propertyName, int pageNumber) const 153 { 154 JSRetainPtr<JSStringRef> propertyValue(Adopt, JSStringCreateWithUTF8CString(DumpRenderTreeSupportGtk::pageProperty(mainFrame, propertyName, pageNumber).data())); 155 return propertyValue; 156 } 157 158 bool LayoutTestController::isPageBoxVisible(int pageNumber) const 159 { 160 return DumpRenderTreeSupportGtk::isPageBoxVisible(mainFrame, pageNumber); 161 } 162 163 JSRetainPtr<JSStringRef> LayoutTestController::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) const 164 { 165 JSRetainPtr<JSStringRef> propertyValue(Adopt, JSStringCreateWithUTF8CString(DumpRenderTreeSupportGtk::pageSizeAndMarginsInPixels(mainFrame, pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft).data())); 166 return propertyValue; 167 } 168 169 size_t LayoutTestController::webHistoryItemCount() 170 { 171 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); 172 WebKitWebBackForwardList* list = webkit_web_view_get_back_forward_list(webView); 173 174 if (!list) 175 return -1; 176 177 // We do not add the current page to the total count as it's not 178 // considered in DRT tests 179 return webkit_web_back_forward_list_get_back_length(list) + 180 webkit_web_back_forward_list_get_forward_length(list); 181 } 182 183 unsigned LayoutTestController::workerThreadCount() const 184 { 185 return DumpRenderTreeSupportGtk::workerThreadCount(); 186 } 187 188 void LayoutTestController::notifyDone() 189 { 190 if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count()) 191 dump(); 192 m_waitToDump = false; 193 waitForPolicy = false; 194 } 195 196 JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url) 197 { 198 // Function introduced in r28690. This may need special-casing on Windows. 199 return JSStringRetain(url); // Do nothing on Unix. 200 } 201 202 void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target) 203 { 204 gchar* relativeURL = JSStringCopyUTF8CString(url); 205 SoupURI* baseURI = soup_uri_new(webkit_web_frame_get_uri(mainFrame)); 206 207 SoupURI* absoluteURI = soup_uri_new_with_base(baseURI, relativeURL); 208 soup_uri_free(baseURI); 209 g_free(relativeURL); 210 211 gchar* absoluteCString; 212 if (absoluteURI) { 213 absoluteCString = soup_uri_to_string(absoluteURI, FALSE); 214 soup_uri_free(absoluteURI); 215 } else 216 absoluteCString = JSStringCopyUTF8CString(url); 217 218 JSRetainPtr<JSStringRef> absoluteURL(Adopt, JSStringCreateWithUTF8CString(absoluteCString)); 219 g_free(absoluteCString); 220 221 WorkQueue::shared()->queue(new LoadItem(absoluteURL.get(), target)); 222 } 223 224 void LayoutTestController::setAcceptsEditing(bool acceptsEditing) 225 { 226 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); 227 webkit_web_view_set_editable(webView, acceptsEditing); 228 } 229 230 void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies) 231 { 232 SoupSession* session = webkit_get_default_session(); 233 SoupCookieJar* jar = reinterpret_cast<SoupCookieJar*>(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR)); 234 235 /* If the jar was not created - we create it on demand, i.e, just 236 in case we have HTTP requests - then we must create it here in 237 order to set the proper accept policy */ 238 if (!jar) { 239 jar = soup_cookie_jar_new(); 240 soup_session_add_feature(session, SOUP_SESSION_FEATURE(jar)); 241 g_object_unref(jar); 242 } 243 244 SoupCookieJarAcceptPolicy policy; 245 246 if (alwaysAcceptCookies) 247 policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; 248 else 249 policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY; 250 251 g_object_set(G_OBJECT(jar), SOUP_COOKIE_JAR_ACCEPT_POLICY, policy, NULL); 252 } 253 254 void LayoutTestController::setCustomPolicyDelegate(bool setDelegate, bool permissive) 255 { 256 // FIXME: implement 257 } 258 259 void LayoutTestController::waitForPolicyDelegate() 260 { 261 waitForPolicy = true; 262 setWaitToDump(true); 263 } 264 265 void LayoutTestController::setScrollbarPolicy(JSStringRef orientation, JSStringRef policy) 266 { 267 // FIXME: implement 268 } 269 270 void LayoutTestController::addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef protocol, JSStringRef host, bool includeSubdomains) 271 { 272 gchar* sourceOriginGChar = JSStringCopyUTF8CString(sourceOrigin); 273 gchar* protocolGChar = JSStringCopyUTF8CString(protocol); 274 gchar* hostGChar = JSStringCopyUTF8CString(host); 275 DumpRenderTreeSupportGtk::whiteListAccessFromOrigin(sourceOriginGChar, protocolGChar, hostGChar, includeSubdomains); 276 g_free(sourceOriginGChar); 277 g_free(protocolGChar); 278 g_free(hostGChar); 279 } 280 281 void LayoutTestController::removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef protocol, JSStringRef host, bool includeSubdomains) 282 { 283 // FIXME: implement 284 } 285 286 void LayoutTestController::setMainFrameIsFirstResponder(bool flag) 287 { 288 // FIXME: implement 289 } 290 291 void LayoutTestController::setTabKeyCyclesThroughElements(bool cycles) 292 { 293 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); 294 WebKitWebSettings* settings = webkit_web_view_get_settings(webView); 295 g_object_set(G_OBJECT(settings), "tab-key-cycles-through-elements", cycles, NULL); 296 } 297 298 void LayoutTestController::setTimelineProfilingEnabled(bool flag) 299 { 300 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 301 ASSERT(view); 302 303 WebKitWebInspector* inspector = webkit_web_view_get_inspector(view); 304 g_object_set(G_OBJECT(inspector), "timeline-profiling-enabled", flag, NULL); 305 } 306 307 void LayoutTestController::setUseDashboardCompatibilityMode(bool flag) 308 { 309 // FIXME: implement 310 } 311 312 static gchar* userStyleSheet = NULL; 313 static gboolean userStyleSheetEnabled = TRUE; 314 315 void LayoutTestController::setUserStyleSheetEnabled(bool flag) 316 { 317 userStyleSheetEnabled = flag; 318 319 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); 320 WebKitWebSettings* settings = webkit_web_view_get_settings(webView); 321 if (flag && userStyleSheet) 322 g_object_set(G_OBJECT(settings), "user-stylesheet-uri", userStyleSheet, NULL); 323 else 324 g_object_set(G_OBJECT(settings), "user-stylesheet-uri", "", NULL); 325 } 326 327 void LayoutTestController::setUserStyleSheetLocation(JSStringRef path) 328 { 329 g_free(userStyleSheet); 330 userStyleSheet = JSStringCopyUTF8CString(path); 331 if (userStyleSheetEnabled) 332 setUserStyleSheetEnabled(true); 333 } 334 335 void LayoutTestController::setValueForUser(JSContextRef context, JSValueRef nodeObject, JSStringRef value) 336 { 337 DumpRenderTreeSupportGtk::setValueForUser(context, nodeObject, value); 338 } 339 340 void LayoutTestController::setViewModeMediaFeature(JSStringRef mode) 341 { 342 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 343 ASSERT(view); 344 345 char* viewMode = JSStringCopyUTF8CString(mode); 346 347 if (!g_strcmp0(viewMode, "windowed")) 348 webkit_web_view_set_view_mode(view, WEBKIT_WEB_VIEW_VIEW_MODE_WINDOWED); 349 else if (!g_strcmp0(viewMode, "floating")) 350 webkit_web_view_set_view_mode(view, WEBKIT_WEB_VIEW_VIEW_MODE_FLOATING); 351 else if (!g_strcmp0(viewMode, "fullscreen")) 352 webkit_web_view_set_view_mode(view, WEBKIT_WEB_VIEW_VIEW_MODE_FULLSCREEN); 353 else if (!g_strcmp0(viewMode, "maximized")) 354 webkit_web_view_set_view_mode(view, WEBKIT_WEB_VIEW_VIEW_MODE_MAXIMIZED); 355 else if (!g_strcmp0(viewMode, "minimized")) 356 webkit_web_view_set_view_mode(view, WEBKIT_WEB_VIEW_VIEW_MODE_MINIMIZED); 357 358 g_free(viewMode); 359 } 360 361 void LayoutTestController::setWindowIsKey(bool windowIsKey) 362 { 363 // FIXME: implement 364 } 365 366 void LayoutTestController::setSmartInsertDeleteEnabled(bool flag) 367 { 368 // FIXME: implement 369 } 370 371 static gboolean waitToDumpWatchdogFired(void*) 372 { 373 waitToDumpWatchdog = 0; 374 gLayoutTestController->waitToDumpWatchdogTimerFired(); 375 return FALSE; 376 } 377 378 void LayoutTestController::setWaitToDump(bool waitUntilDone) 379 { 380 static const int timeoutSeconds = 30; 381 382 m_waitToDump = waitUntilDone; 383 if (m_waitToDump && !waitToDumpWatchdog) 384 waitToDumpWatchdog = g_timeout_add_seconds(timeoutSeconds, waitToDumpWatchdogFired, 0); 385 } 386 387 int LayoutTestController::windowCount() 388 { 389 // +1 -> including the main view 390 return g_slist_length(webViewList) + 1; 391 } 392 393 void LayoutTestController::setPrivateBrowsingEnabled(bool flag) 394 { 395 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 396 ASSERT(view); 397 398 WebKitWebSettings* settings = webkit_web_view_get_settings(view); 399 g_object_set(G_OBJECT(settings), "enable-private-browsing", flag, NULL); 400 } 401 402 void LayoutTestController::setJavaScriptCanAccessClipboard(bool flag) 403 { 404 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 405 ASSERT(view); 406 407 WebKitWebSettings* settings = webkit_web_view_get_settings(view); 408 g_object_set(G_OBJECT(settings), "javascript-can-access-clipboard", flag, NULL); 409 } 410 411 void LayoutTestController::setXSSAuditorEnabled(bool flag) 412 { 413 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 414 ASSERT(view); 415 416 WebKitWebSettings* settings = webkit_web_view_get_settings(view); 417 g_object_set(G_OBJECT(settings), "enable-xss-auditor", flag, NULL); 418 } 419 420 void LayoutTestController::setFrameFlatteningEnabled(bool flag) 421 { 422 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 423 ASSERT(view); 424 425 WebKitWebSettings* settings = webkit_web_view_get_settings(view); 426 g_object_set(G_OBJECT(settings), "enable-frame-flattening", flag, NULL); 427 } 428 429 void LayoutTestController::setSpatialNavigationEnabled(bool flag) 430 { 431 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 432 ASSERT(view); 433 434 WebKitWebSettings* settings = webkit_web_view_get_settings(view); 435 g_object_set(G_OBJECT(settings), "enable-spatial-navigation", flag, NULL); 436 } 437 438 void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool flag) 439 { 440 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 441 ASSERT(view); 442 443 WebKitWebSettings* settings = webkit_web_view_get_settings(view); 444 g_object_set(G_OBJECT(settings), "enable-universal-access-from-file-uris", flag, NULL); 445 } 446 447 void LayoutTestController::setAllowFileAccessFromFileURLs(bool flag) 448 { 449 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 450 ASSERT(view); 451 452 WebKitWebSettings* settings = webkit_web_view_get_settings(view); 453 g_object_set(G_OBJECT(settings), "enable-file-access-from-file-uris", flag, NULL); 454 } 455 456 void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag) 457 { 458 // FIXME: implement 459 } 460 461 void LayoutTestController::setAutofilled(JSContextRef context, JSValueRef nodeObject, bool isAutofilled) 462 { 463 DumpRenderTreeSupportGtk::setAutofilled(context, nodeObject, isAutofilled); 464 } 465 466 void LayoutTestController::disableImageLoading() 467 { 468 // FIXME: Implement for testing fix for https://bugs.webkit.org/show_bug.cgi?id=27896 469 // Also need to make sure image loading is re-enabled for each new test. 470 } 471 472 void LayoutTestController::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma) 473 { 474 // FIXME: Implement for DeviceOrientation layout tests. 475 // See https://bugs.webkit.org/show_bug.cgi?id=30335. 476 } 477 478 void LayoutTestController::setMockGeolocationPosition(double latitude, double longitude, double accuracy) 479 { 480 // FIXME: Implement for Geolocation layout tests. 481 // See https://bugs.webkit.org/show_bug.cgi?id=28264. 482 } 483 484 void LayoutTestController::setMockGeolocationError(int code, JSStringRef message) 485 { 486 // FIXME: Implement for Geolocation layout tests. 487 // See https://bugs.webkit.org/show_bug.cgi?id=28264. 488 } 489 490 void LayoutTestController::setGeolocationPermission(bool allow) 491 { 492 // FIXME: Implement for Geolocation layout tests. 493 setGeolocationPermissionCommon(allow); 494 } 495 496 int LayoutTestController::numberOfPendingGeolocationPermissionRequests() 497 { 498 // FIXME: Implement for Geolocation layout tests. 499 return -1; 500 } 501 502 void LayoutTestController::addMockSpeechInputResult(JSStringRef result, double confidence, JSStringRef language) 503 { 504 // FIXME: Implement for speech input layout tests. 505 // See https://bugs.webkit.org/show_bug.cgi?id=39485. 506 } 507 508 void LayoutTestController::setIconDatabaseEnabled(bool enabled) 509 { 510 WebKitIconDatabase* database = webkit_get_icon_database(); 511 if (enabled) { 512 GOwnPtr<gchar> iconDatabasePath(g_build_filename(g_get_tmp_dir(), "DumpRenderTree", "icondatabase", NULL)); 513 webkit_icon_database_set_path(database, iconDatabasePath.get()); 514 } else 515 webkit_icon_database_set_path(database, 0); 516 } 517 518 void LayoutTestController::setJavaScriptProfilingEnabled(bool flag) 519 { 520 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 521 ASSERT(view); 522 523 setDeveloperExtrasEnabled(flag); 524 525 WebKitWebInspector* inspector = webkit_web_view_get_inspector(view); 526 g_object_set(G_OBJECT(inspector), "javascript-profiling-enabled", flag, NULL); 527 } 528 529 void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag) 530 { 531 DumpRenderTreeSupportGtk::setSelectTrailingWhitespaceEnabled(flag); 532 } 533 534 void LayoutTestController::setPopupBlockingEnabled(bool flag) 535 { 536 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 537 ASSERT(view); 538 539 WebKitWebSettings* settings = webkit_web_view_get_settings(view); 540 g_object_set(G_OBJECT(settings), "javascript-can-open-windows-automatically", !flag, NULL); 541 542 } 543 544 void LayoutTestController::setPluginsEnabled(bool flag) 545 { 546 // FIXME: Implement 547 } 548 549 bool LayoutTestController::elementDoesAutoCompleteForElementWithId(JSStringRef id) 550 { 551 // FIXME: implement 552 return false; 553 } 554 555 void LayoutTestController::execCommand(JSStringRef name, JSStringRef value) 556 { 557 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 558 ASSERT(view); 559 560 gchar* cName = JSStringCopyUTF8CString(name); 561 gchar* cValue = JSStringCopyUTF8CString(value); 562 DumpRenderTreeSupportGtk::executeCoreCommandByName(view, cName, cValue); 563 g_free(cName); 564 g_free(cValue); 565 } 566 567 bool LayoutTestController::findString(JSContextRef context, JSStringRef target, JSObjectRef optionsArray) 568 { 569 WebKitFindOptions findOptions = 0; 570 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); 571 ASSERT(webView); 572 573 JSRetainPtr<JSStringRef> lengthPropertyName(Adopt, JSStringCreateWithUTF8CString("length")); 574 JSValueRef lengthValue = JSObjectGetProperty(context, optionsArray, lengthPropertyName.get(), 0); 575 if (!JSValueIsNumber(context, lengthValue)) 576 return false; 577 578 GOwnPtr<gchar> targetString(JSStringCopyUTF8CString(target)); 579 580 size_t length = static_cast<size_t>(JSValueToNumber(context, lengthValue, 0)); 581 for (size_t i = 0; i < length; ++i) { 582 JSValueRef value = JSObjectGetPropertyAtIndex(context, optionsArray, i, 0); 583 if (!JSValueIsString(context, value)) 584 continue; 585 586 JSRetainPtr<JSStringRef> optionName(Adopt, JSValueToStringCopy(context, value, 0)); 587 588 if (JSStringIsEqualToUTF8CString(optionName.get(), "CaseInsensitive")) 589 findOptions |= WebKit::WebFindOptionsCaseInsensitive; 590 else if (JSStringIsEqualToUTF8CString(optionName.get(), "AtWordStarts")) 591 findOptions |= WebKit::WebFindOptionsAtWordStarts; 592 else if (JSStringIsEqualToUTF8CString(optionName.get(), "TreatMedialCapitalAsWordStart")) 593 findOptions |= WebKit::WebFindOptionsTreatMedialCapitalAsWordStart; 594 else if (JSStringIsEqualToUTF8CString(optionName.get(), "Backwards")) 595 findOptions |= WebKit::WebFindOptionsBackwards; 596 else if (JSStringIsEqualToUTF8CString(optionName.get(), "WrapAround")) 597 findOptions |= WebKit::WebFindOptionsWrapAround; 598 else if (JSStringIsEqualToUTF8CString(optionName.get(), "StartInSelection")) 599 findOptions |= WebKit::WebFindOptionsStartInSelection; 600 } 601 602 return DumpRenderTreeSupportGtk::findString(webView, targetString.get(), findOptions); 603 } 604 605 bool LayoutTestController::isCommandEnabled(JSStringRef name) 606 { 607 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 608 ASSERT(view); 609 610 gchar* cName = JSStringCopyUTF8CString(name); 611 bool result = DumpRenderTreeSupportGtk::isCommandEnabled(view, cName); 612 g_free(cName); 613 return result; 614 } 615 616 void LayoutTestController::setCacheModel(int cacheModel) 617 { 618 // These constants are derived from the Mac cache model enum in Source/WebKit/mac/WebView/WebPreferences.h. 619 switch (cacheModel) { 620 case 0: 621 webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER); 622 break; 623 case 1: 624 webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER); 625 break; 626 case 3: 627 webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER); 628 break; 629 default: 630 ASSERT_NOT_REACHED(); 631 } 632 } 633 634 void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL) 635 { 636 // FIXME: implement 637 } 638 639 void LayoutTestController::clearPersistentUserStyleSheet() 640 { 641 // FIXME: implement 642 } 643 644 void LayoutTestController::clearAllApplicationCaches() 645 { 646 // FIXME: Implement to support application cache quotas. 647 } 648 649 void LayoutTestController::setApplicationCacheOriginQuota(unsigned long long quota) 650 { 651 // FIXME: Implement to support application cache quotas. 652 } 653 654 void LayoutTestController::clearApplicationCacheForOrigin(OpaqueJSString*) 655 { 656 // FIXME: Implement to support deleting all application caches for an origin. 657 } 658 659 JSValueRef LayoutTestController::originsWithApplicationCache(JSContextRef context) 660 { 661 // FIXME: Implement to get origins that contain application caches. 662 return JSValueMakeUndefined(context); 663 } 664 665 void LayoutTestController::clearAllDatabases() 666 { 667 webkit_remove_all_web_databases(); 668 } 669 670 void LayoutTestController::setDatabaseQuota(unsigned long long quota) 671 { 672 WebKitSecurityOrigin* origin = webkit_web_frame_get_security_origin(mainFrame); 673 webkit_security_origin_set_web_database_quota(origin, quota); 674 } 675 676 JSValueRef LayoutTestController::originsWithLocalStorage(JSContextRef context) 677 { 678 // FIXME: implement 679 return JSValueMakeUndefined(context); 680 } 681 682 void LayoutTestController::deleteAllLocalStorage() 683 { 684 // FIXME: implement 685 } 686 687 void LayoutTestController::deleteLocalStorageForOrigin(JSStringRef originIdentifier) 688 { 689 // FIXME: implement 690 } 691 692 void LayoutTestController::observeStorageTrackerNotifications(unsigned number) 693 { 694 // FIXME: implement 695 } 696 697 void LayoutTestController::syncLocalStorage() 698 { 699 // FIXME: implement 700 } 701 702 void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(bool, JSStringRef) 703 { 704 // FIXME: implement 705 } 706 707 void LayoutTestController::setAppCacheMaximumSize(unsigned long long size) 708 { 709 webkit_application_cache_set_maximum_size(size); 710 } 711 712 bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId) 713 { 714 gchar* name = JSStringCopyUTF8CString(animationName); 715 gchar* element = JSStringCopyUTF8CString(elementId); 716 bool returnValue = DumpRenderTreeSupportGtk::pauseAnimation(mainFrame, name, time, element); 717 g_free(name); 718 g_free(element); 719 return returnValue; 720 } 721 722 bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName, double time, JSStringRef elementId) 723 { 724 gchar* name = JSStringCopyUTF8CString(propertyName); 725 gchar* element = JSStringCopyUTF8CString(elementId); 726 bool returnValue = DumpRenderTreeSupportGtk::pauseTransition(mainFrame, name, time, element); 727 g_free(name); 728 g_free(element); 729 return returnValue; 730 } 731 732 bool LayoutTestController::sampleSVGAnimationForElementAtTime(JSStringRef animationId, double time, JSStringRef elementId) 733 { 734 gchar* name = JSStringCopyUTF8CString(animationId); 735 gchar* element = JSStringCopyUTF8CString(elementId); 736 bool returnValue = DumpRenderTreeSupportGtk::pauseSVGAnimation(mainFrame, name, time, element); 737 g_free(name); 738 g_free(element); 739 return returnValue; 740 } 741 742 unsigned LayoutTestController::numberOfActiveAnimations() const 743 { 744 return DumpRenderTreeSupportGtk::numberOfActiveAnimations(mainFrame); 745 } 746 747 void LayoutTestController::suspendAnimations() const 748 { 749 DumpRenderTreeSupportGtk::suspendAnimations(mainFrame); 750 } 751 752 void LayoutTestController::resumeAnimations() const 753 { 754 DumpRenderTreeSupportGtk::resumeAnimations(mainFrame); 755 } 756 757 void LayoutTestController::overridePreference(JSStringRef key, JSStringRef value) 758 { 759 GOwnPtr<gchar> originalName(JSStringCopyUTF8CString(key)); 760 GOwnPtr<gchar> valueAsString(JSStringCopyUTF8CString(value)); 761 762 WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 763 ASSERT(view); 764 765 // This transformation could be handled by a hash table (and it once was), but 766 // having it prominent, makes it easier for people from other ports to keep the 767 // list up to date. 768 const gchar* propertyName = 0; 769 if (g_str_equal(originalName.get(), "WebKitJavaScriptEnabled")) 770 propertyName = "enable-scripts"; 771 else if (g_str_equal(originalName.get(), "WebKitDefaultFontSize")) 772 propertyName = "default-font-size"; 773 else if (g_str_equal(originalName.get(), "WebKitEnableCaretBrowsing")) 774 propertyName = "enable-caret-browsing"; 775 else if (g_str_equal(originalName.get(), "WebKitUsesPageCachePreferenceKey")) 776 propertyName = "enable-page-cache"; 777 else if (g_str_equal(originalName.get(), "WebKitPluginsEnabled")) 778 propertyName = "enable-plugins"; 779 else if (g_str_equal(originalName.get(), "WebKitHyperlinkAuditingEnabled")) 780 propertyName = "enable-hyperlink-auditing"; 781 else if (g_str_equal(originalName.get(), "WebKitWebGLEnabled")) 782 propertyName = "enable-webgl"; 783 else if (g_str_equal(originalName.get(), "WebKitTabToLinksPreferenceKey")) { 784 DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(!g_ascii_strcasecmp(valueAsString.get(), "true") || !g_ascii_strcasecmp(valueAsString.get(), "1")); 785 return; 786 } else { 787 fprintf(stderr, "LayoutTestController::overridePreference tried to override " 788 "unknown preference '%s'.\n", originalName.get()); 789 return; 790 } 791 792 WebKitWebSettings* settings = webkit_web_view_get_settings(view); 793 GParamSpec* pspec = g_object_class_find_property(G_OBJECT_CLASS( 794 WEBKIT_WEB_SETTINGS_GET_CLASS(settings)), propertyName); 795 GValue currentPropertyValue = { 0, { { 0 } } }; 796 g_value_init(¤tPropertyValue, pspec->value_type); 797 798 if (G_VALUE_HOLDS_STRING(¤tPropertyValue)) 799 g_object_set(settings, propertyName, valueAsString.get(), NULL); 800 else if (G_VALUE_HOLDS_BOOLEAN(¤tPropertyValue)) 801 g_object_set(G_OBJECT(settings), propertyName, !g_ascii_strcasecmp(valueAsString.get(), "true") 802 || !g_ascii_strcasecmp(valueAsString.get(), "1"), NULL); 803 else if (G_VALUE_HOLDS_INT(¤tPropertyValue)) 804 g_object_set(G_OBJECT(settings), propertyName, atoi(valueAsString.get()), NULL); 805 else if (G_VALUE_HOLDS_FLOAT(¤tPropertyValue)) { 806 gfloat newValue = g_ascii_strtod(valueAsString.get(), 0); 807 g_object_set(G_OBJECT(settings), propertyName, newValue, NULL); 808 } else 809 fprintf(stderr, "LayoutTestController::overridePreference failed to override " 810 "preference '%s'.\n", originalName.get()); 811 } 812 813 void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart, bool allFrames) 814 { 815 printf("LayoutTestController::addUserScript not implemented.\n"); 816 } 817 818 void LayoutTestController::addUserStyleSheet(JSStringRef source, bool allFrames) 819 { 820 GOwnPtr<gchar> sourceCode(JSStringCopyUTF8CString(source)); 821 DumpRenderTreeSupportGtk::addUserStyleSheet(mainFrame, sourceCode.get(), allFrames); 822 // FIXME: needs more investigation why userscripts/user-style-top-frame-only.html fails when allFrames is false. 823 824 } 825 826 void LayoutTestController::setDeveloperExtrasEnabled(bool enabled) 827 { 828 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); 829 WebKitWebSettings* webSettings = webkit_web_view_get_settings(webView); 830 831 g_object_set(webSettings, "enable-developer-extras", enabled, NULL); 832 } 833 834 void LayoutTestController::setAsynchronousSpellCheckingEnabled(bool) 835 { 836 // FIXME: Implement this. 837 } 838 839 void LayoutTestController::showWebInspector() 840 { 841 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); 842 WebKitWebInspector* inspector = webkit_web_view_get_inspector(webView); 843 844 webkit_web_inspector_show(inspector); 845 } 846 847 void LayoutTestController::closeWebInspector() 848 { 849 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); 850 WebKitWebInspector* inspector = webkit_web_view_get_inspector(webView); 851 852 webkit_web_inspector_close(inspector); 853 } 854 855 void LayoutTestController::evaluateInWebInspector(long callId, JSStringRef script) 856 { 857 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); 858 WebKitWebInspector* inspector = webkit_web_view_get_inspector(webView); 859 char* scriptString = JSStringCopyUTF8CString(script); 860 861 webkit_web_inspector_execute_script(inspector, callId, scriptString); 862 g_free(scriptString); 863 } 864 865 void LayoutTestController::evaluateScriptInIsolatedWorld(unsigned worldID, JSObjectRef globalObject, JSStringRef script) 866 { 867 // FIXME: Implement this. 868 } 869 870 void LayoutTestController::removeAllVisitedLinks() 871 { 872 // FIXME: Implement this. 873 } 874 875 bool LayoutTestController::callShouldCloseOnWebView() 876 { 877 // FIXME: Implement for testing fix for https://bugs.webkit.org/show_bug.cgi?id=27481 878 return false; 879 } 880 881 void LayoutTestController::apiTestNewWindowDataLoadBaseURL(JSStringRef utf8Data, JSStringRef baseURL) 882 { 883 884 } 885 886 void LayoutTestController::apiTestGoToCurrentBackForwardItem() 887 { 888 889 } 890 891 void LayoutTestController::setWebViewEditable(bool) 892 { 893 } 894 895 JSRetainPtr<JSStringRef> LayoutTestController::markerTextForListItem(JSContextRef context, JSValueRef nodeObject) const 896 { 897 CString markerTextGChar = DumpRenderTreeSupportGtk::markerTextForListItem(mainFrame, context, nodeObject); 898 if (markerTextGChar.isNull()) 899 return 0; 900 901 JSRetainPtr<JSStringRef> markerText(Adopt, JSStringCreateWithUTF8CString(markerTextGChar.data())); 902 return markerText; 903 } 904 905 void LayoutTestController::authenticateSession(JSStringRef, JSStringRef, JSStringRef) 906 { 907 } 908 909 void LayoutTestController::setEditingBehavior(const char* editingBehavior) 910 { 911 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); 912 WebKitWebSettings* settings = webkit_web_view_get_settings(webView); 913 914 if (!strcmp(editingBehavior, "win")) 915 g_object_set(G_OBJECT(settings), "editing-behavior", WEBKIT_EDITING_BEHAVIOR_WINDOWS, NULL); 916 else if (!strcmp(editingBehavior, "mac")) 917 g_object_set(G_OBJECT(settings), "editing-behavior", WEBKIT_EDITING_BEHAVIOR_MAC, NULL); 918 else if (!strcmp(editingBehavior, "unix")) 919 g_object_set(G_OBJECT(settings), "editing-behavior", WEBKIT_EDITING_BEHAVIOR_UNIX, NULL); 920 } 921 922 JSValueRef LayoutTestController::shadowRoot(JSContextRef context, JSValueRef element) 923 { 924 return DumpRenderTreeSupportGtk::shadowRoot(context, element); 925 } 926 927 void LayoutTestController::abortModal() 928 { 929 } 930 931 bool LayoutTestController::hasSpellingMarker(int from, int length) 932 { 933 return DumpRenderTreeSupportGtk::webkitWebFrameSelectionHasSpellingMarker(mainFrame, from, length); 934 } 935 936 bool LayoutTestController::hasGrammarMarker(int from, int length) 937 { 938 return false; 939 } 940 941 void LayoutTestController::dumpConfigurationForViewport(int deviceDPI, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight) 942 { 943 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); 944 ASSERT(webView); 945 DumpRenderTreeSupportGtk::dumpConfigurationForViewport(webView, deviceDPI, deviceWidth, deviceHeight, availableWidth, availableHeight); 946 } 947 948 void LayoutTestController::setSerializeHTTPLoads(bool) 949 { 950 // FIXME: Implement if needed for https://bugs.webkit.org/show_bug.cgi?id=50758. 951 } 952 953 void LayoutTestController::setMinimumTimerInterval(double minimumTimerInterval) 954 { 955 WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); 956 DumpRenderTreeSupportGtk::setMinimumTimerInterval(webView, minimumTimerInterval); 957 } 958