Home | History | Annotate | Download | only in gtk
      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(&currentPropertyValue, pspec->value_type);
    797 
    798     if (G_VALUE_HOLDS_STRING(&currentPropertyValue))
    799         g_object_set(settings, propertyName, valueAsString.get(), NULL);
    800     else if (G_VALUE_HOLDS_BOOLEAN(&currentPropertyValue))
    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(&currentPropertyValue))
    804         g_object_set(G_OBJECT(settings), propertyName, atoi(valueAsString.get()), NULL);
    805     else if (G_VALUE_HOLDS_FLOAT(&currentPropertyValue)) {
    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