Home | History | Annotate | Download | only in WebCoreSupport
      1 /*
      2  *  Copyright (C) Research In Motion Limited 2010. All rights reserved.
      3  *  Copyright (C) 2010 Joone Hur <joone (at) kldp.org>
      4  *  Copyright (C) 2009 Google Inc. All rights reserved.
      5  *  Copyright (C) 2011 Igalia S.L.
      6  *
      7  *  This library is free software; you can redistribute it and/or
      8  *  modify it under the terms of the GNU Lesser General Public
      9  *  License as published by the Free Software Foundation; either
     10  *  version 2 of the License, or (at your option) any later version.
     11  *
     12  *  This library is distributed in the hope that it will be useful,
     13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  *  Lesser General Public License for more details.
     16  *
     17  *  You should have received a copy of the GNU Lesser General Public
     18  *  License along with this library; if not, write to the Free Software
     19  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     20  */
     21 
     22 #include "config.h"
     23 #include "DumpRenderTreeSupportGtk.h"
     24 
     25 #include "APICast.h"
     26 #include "AXObjectCache.h"
     27 #include "AccessibilityObjectWrapperAtk.h"
     28 #include "AnimationController.h"
     29 #include "DOMWrapperWorld.h"
     30 #include "Document.h"
     31 #include "Element.h"
     32 #include "FocusController.h"
     33 #include "FrameLoaderClientGtk.h"
     34 #include "FrameTree.h"
     35 #include "FrameView.h"
     36 #include "GCController.h"
     37 #include "GraphicsContext.h"
     38 #include "HTMLInputElement.h"
     39 #include "InputElement.h"
     40 #include "JSDOMWindow.h"
     41 #include "JSDocument.h"
     42 #include "JSElement.h"
     43 #include "JSLock.h"
     44 #include "JSNodeList.h"
     45 #include "JSRange.h"
     46 #include "JSValue.h"
     47 #include "NodeList.h"
     48 #include "PageGroup.h"
     49 #include "PlatformString.h"
     50 #include "PrintContext.h"
     51 #include "RenderListItem.h"
     52 #include "RenderTreeAsText.h"
     53 #include "RenderView.h"
     54 #include "SecurityOrigin.h"
     55 #include "Settings.h"
     56 #include "TextIterator.h"
     57 #include "WebKitDOMRangePrivate.h"
     58 #include "WorkerThread.h"
     59 #include "webkitglobalsprivate.h"
     60 #include "webkitwebframe.h"
     61 #include "webkitwebframeprivate.h"
     62 #include "webkitwebview.h"
     63 #include "webkitwebviewprivate.h"
     64 #include <JavaScriptCore/APICast.h>
     65 
     66 #if ENABLE(SVG)
     67 #include "SVGDocumentExtensions.h"
     68 #include "SVGSMILElement.h"
     69 #endif
     70 
     71 using namespace JSC;
     72 using namespace WebCore;
     73 using namespace WebKit;
     74 
     75 bool DumpRenderTreeSupportGtk::s_drtRun = false;
     76 bool DumpRenderTreeSupportGtk::s_linksIncludedInTabChain = true;
     77 bool DumpRenderTreeSupportGtk::s_selectTrailingWhitespaceEnabled = false;
     78 
     79 DumpRenderTreeSupportGtk::DumpRenderTreeSupportGtk()
     80 {
     81 }
     82 
     83 DumpRenderTreeSupportGtk::~DumpRenderTreeSupportGtk()
     84 {
     85 }
     86 
     87 void DumpRenderTreeSupportGtk::setDumpRenderTreeModeEnabled(bool enabled)
     88 {
     89     s_drtRun = enabled;
     90 }
     91 
     92 bool DumpRenderTreeSupportGtk::dumpRenderTreeModeEnabled()
     93 {
     94     return s_drtRun;
     95 }
     96 void DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(bool enabled)
     97 {
     98     s_linksIncludedInTabChain = enabled;
     99 }
    100 
    101 bool DumpRenderTreeSupportGtk::linksIncludedInFocusChain()
    102 {
    103     return s_linksIncludedInTabChain;
    104 }
    105 
    106 void DumpRenderTreeSupportGtk::setSelectTrailingWhitespaceEnabled(bool enabled)
    107 {
    108     s_selectTrailingWhitespaceEnabled = enabled;
    109 }
    110 
    111 bool DumpRenderTreeSupportGtk::selectTrailingWhitespaceEnabled()
    112 {
    113     return s_selectTrailingWhitespaceEnabled;
    114 }
    115 
    116 JSValueRef DumpRenderTreeSupportGtk::nodesFromRect(JSContextRef context, JSValueRef value, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping)
    117 {
    118     JSLock lock(SilenceAssertionsOnly);
    119     ExecState* exec = toJS(context);
    120     if (!value)
    121         return JSValueMakeUndefined(context);
    122     JSValue jsValue = toJS(exec, value);
    123     if (!jsValue.inherits(&JSDocument::s_info))
    124        return JSValueMakeUndefined(context);
    125 
    126     JSDocument* jsDocument = static_cast<JSDocument*>(asObject(jsValue));
    127     Document* document = jsDocument->impl();
    128     RefPtr<NodeList> nodes = document->nodesFromRect(x, y, top, right, bottom, left, ignoreClipping);
    129     return toRef(exec, toJS(exec, jsDocument->globalObject(), nodes.get()));
    130 }
    131 
    132 WebKitDOMRange* DumpRenderTreeSupportGtk::jsValueToDOMRange(JSContextRef context, JSValueRef value)
    133 {
    134     if (!value)
    135         return 0;
    136 
    137     JSLock lock(SilenceAssertionsOnly);
    138     ExecState* exec = toJS(context);
    139 
    140     Range* range = toRange(toJS(exec, value));
    141     if (!range)
    142         return 0;
    143     return kit(range);
    144 }
    145 
    146 /**
    147  * getFrameChildren:
    148  * @frame: a #WebKitWebFrame
    149  *
    150  * Return value: child frames of @frame
    151  */
    152 GSList* DumpRenderTreeSupportGtk::getFrameChildren(WebKitWebFrame* frame)
    153 {
    154     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
    155 
    156     Frame* coreFrame = core(frame);
    157     if (!coreFrame)
    158         return 0;
    159 
    160     GSList* children = 0;
    161     for (Frame* child = coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
    162         FrameLoader* loader = child->loader();
    163         WebKit::FrameLoaderClient* client = static_cast<WebKit::FrameLoaderClient*>(loader->client());
    164         if (client)
    165           children = g_slist_append(children, client->webFrame());
    166     }
    167 
    168     return children;
    169 }
    170 
    171 /**
    172  * getInnerText:
    173  * @frame: a #WebKitWebFrame
    174  *
    175  * Return value: inner text of @frame
    176  */
    177 CString DumpRenderTreeSupportGtk::getInnerText(WebKitWebFrame* frame)
    178 {
    179     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), CString(""));
    180 
    181     Frame* coreFrame = core(frame);
    182     if (!coreFrame)
    183         return CString("");
    184 
    185     FrameView* view = coreFrame->view();
    186 
    187     if (view && view->layoutPending())
    188         view->layout();
    189 
    190     Element* documentElement = coreFrame->document()->documentElement();
    191     return documentElement->innerText().utf8();
    192 }
    193 
    194 /**
    195  * dumpRenderTree:
    196  * @frame: a #WebKitWebFrame
    197  *
    198  * Return value: Non-recursive render tree dump of @frame
    199  */
    200 CString DumpRenderTreeSupportGtk::dumpRenderTree(WebKitWebFrame* frame)
    201 {
    202     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), CString(""));
    203 
    204     Frame* coreFrame = core(frame);
    205     if (!coreFrame)
    206         return CString("");
    207 
    208     FrameView* view = coreFrame->view();
    209 
    210     if (view && view->layoutPending())
    211         view->layout();
    212 
    213     return externalRepresentation(coreFrame).utf8();
    214 }
    215 
    216 /**
    217  * counterValueForElementById:
    218  * @frame: a #WebKitWebFrame
    219  * @id: an element ID string
    220  *
    221  * Return value: The counter value of element @id in @frame
    222  */
    223 CString DumpRenderTreeSupportGtk::counterValueForElementById(WebKitWebFrame* frame, const char* id)
    224 {
    225     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), CString());
    226 
    227     Frame* coreFrame = core(frame);
    228     if (!coreFrame)
    229         return CString();
    230 
    231     Element* coreElement = coreFrame->document()->getElementById(AtomicString(id));
    232     if (!coreElement)
    233         return CString();
    234 
    235     return counterValueForElement(coreElement).utf8();
    236 }
    237 
    238 /**
    239  * numberForElementById
    240  * @frame: a #WebKitWebFrame
    241  * @id: an element ID string
    242  * @pageWidth: width of a page
    243  * @pageHeight: height of a page
    244  *
    245  * Return value: The number of page where the specified element will be put
    246  */
    247 int DumpRenderTreeSupportGtk::pageNumberForElementById(WebKitWebFrame* frame, const char* id, float pageWidth, float pageHeight)
    248 {
    249     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
    250 
    251     Frame* coreFrame = core(frame);
    252     if (!coreFrame)
    253         return -1;
    254 
    255     Element* coreElement = coreFrame->document()->getElementById(AtomicString(id));
    256     if (!coreElement)
    257         return -1;
    258     return PrintContext::pageNumberForElement(coreElement, FloatSize(pageWidth, pageHeight));
    259 }
    260 
    261 /**
    262  * numberOfPagesForFrame
    263  * @frame: a #WebKitWebFrame
    264  * @pageWidth: width of a page
    265  * @pageHeight: height of a page
    266  *
    267  * Return value: The number of pages to be printed.
    268  */
    269 int DumpRenderTreeSupportGtk::numberOfPagesForFrame(WebKitWebFrame* frame, float pageWidth, float pageHeight)
    270 {
    271     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
    272 
    273     Frame* coreFrame = core(frame);
    274     if (!coreFrame)
    275         return -1;
    276 
    277     return PrintContext::numberOfPages(coreFrame, FloatSize(pageWidth, pageHeight));
    278 }
    279 
    280 /**
    281  * pageProperty
    282  * @frame: a #WebKitWebFrame
    283  * @propertyName: name of a property
    284  * @pageNumber: number of a page
    285  *
    286  * Return value: The value of the given property name.
    287  */
    288 CString DumpRenderTreeSupportGtk::pageProperty(WebKitWebFrame* frame, const char* propertyName, int pageNumber)
    289 {
    290     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), CString());
    291 
    292     Frame* coreFrame = core(frame);
    293     if (!coreFrame)
    294         return CString();
    295 
    296     return PrintContext::pageProperty(coreFrame, propertyName, pageNumber).utf8();
    297 }
    298 
    299 /**
    300  * isPageBoxVisible
    301  * @frame: a #WebKitWebFrame
    302  * @pageNumber: number of a page
    303  *
    304  * Return value: TRUE if a page box is visible.
    305  */
    306 bool DumpRenderTreeSupportGtk::isPageBoxVisible(WebKitWebFrame* frame, int pageNumber)
    307 {
    308     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), false);
    309 
    310     Frame* coreFrame = core(frame);
    311     if (!coreFrame)
    312         return false;
    313 
    314     return coreFrame->document()->isPageBoxVisible(pageNumber);
    315 }
    316 
    317 /**
    318  * pageSizeAndMarginsInPixels
    319  * @frame: a #WebKitWebFrame
    320  * @pageNumber: number of a page
    321  * @width: width of a page
    322  * @height: height of a page
    323  * @marginTop: top margin of a page
    324  * @marginRight: right margin of a page
    325  * @marginBottom: bottom margin of a page
    326  * @marginLeft: left margin of a page
    327  *
    328  * Return value: The value of page size and margin.
    329  */
    330 CString DumpRenderTreeSupportGtk::pageSizeAndMarginsInPixels(WebKitWebFrame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft)
    331 {
    332     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), CString());
    333 
    334     Frame* coreFrame = core(frame);
    335     if (!coreFrame)
    336         return CString();
    337 
    338     return PrintContext::pageSizeAndMarginsInPixels(coreFrame, pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft).utf8();
    339 }
    340 
    341 /**
    342  * addUserStyleSheet
    343  * @frame: a #WebKitWebFrame
    344  * @sourceCode: code of a user stylesheet
    345  *
    346  */
    347 void DumpRenderTreeSupportGtk::addUserStyleSheet(WebKitWebFrame* frame, const char* sourceCode, bool allFrames)
    348 {
    349     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
    350 
    351     Frame* coreFrame = core(frame);
    352     if (!coreFrame)
    353         return;
    354 
    355     WebKitWebView* webView = getViewFromFrame(frame);
    356     Page* page = core(webView);
    357     page->group().addUserStyleSheetToWorld(mainThreadNormalWorld(), sourceCode, KURL(), 0, 0, allFrames ? InjectInAllFrames : InjectInTopFrameOnly);
    358 }
    359 
    360 /**
    361  * getPendingUnloadEventCount:
    362  * @frame: a #WebKitWebFrame
    363  *
    364  * Return value: number of pending unload events
    365  */
    366 guint DumpRenderTreeSupportGtk::getPendingUnloadEventCount(WebKitWebFrame* frame)
    367 {
    368     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
    369 
    370     return core(frame)->domWindow()->pendingUnloadEventListeners();
    371 }
    372 
    373 bool DumpRenderTreeSupportGtk::pauseAnimation(WebKitWebFrame* frame, const char* name, double time, const char* element)
    374 {
    375     ASSERT(core(frame));
    376     Element* coreElement = core(frame)->document()->getElementById(AtomicString(element));
    377     if (!coreElement || !coreElement->renderer())
    378         return false;
    379     return core(frame)->animation()->pauseAnimationAtTime(coreElement->renderer(), AtomicString(name), time);
    380 }
    381 
    382 bool DumpRenderTreeSupportGtk::pauseTransition(WebKitWebFrame* frame, const char* name, double time, const char* element)
    383 {
    384     ASSERT(core(frame));
    385     Element* coreElement = core(frame)->document()->getElementById(AtomicString(element));
    386     if (!coreElement || !coreElement->renderer())
    387         return false;
    388     return core(frame)->animation()->pauseTransitionAtTime(coreElement->renderer(), AtomicString(name), time);
    389 }
    390 
    391 bool DumpRenderTreeSupportGtk::pauseSVGAnimation(WebKitWebFrame* frame, const char* animationId, double time, const char* elementId)
    392 {
    393     ASSERT(core(frame));
    394 #if ENABLE(SVG)
    395     Document* document = core(frame)->document();
    396     if (!document || !document->svgExtensions())
    397         return false;
    398     Element* coreElement = document->getElementById(AtomicString(animationId));
    399     if (!coreElement || !SVGSMILElement::isSMILElement(coreElement))
    400         return false;
    401     return document->accessSVGExtensions()->sampleAnimationAtTime(elementId, static_cast<SVGSMILElement*>(coreElement), time);
    402 #else
    403     return false;
    404 #endif
    405 }
    406 
    407 CString DumpRenderTreeSupportGtk::markerTextForListItem(WebKitWebFrame* frame, JSContextRef context, JSValueRef nodeObject)
    408 {
    409     JSC::ExecState* exec = toJS(context);
    410     Element* element = toElement(toJS(exec, nodeObject));
    411     if (!element)
    412         return CString();
    413 
    414     return WebCore::markerTextForListItem(element).utf8();
    415 }
    416 
    417 unsigned int DumpRenderTreeSupportGtk::numberOfActiveAnimations(WebKitWebFrame* frame)
    418 {
    419     Frame* coreFrame = core(frame);
    420     if (!coreFrame)
    421         return 0;
    422 
    423     return coreFrame->animation()->numberOfActiveAnimations();
    424 }
    425 
    426 void DumpRenderTreeSupportGtk::suspendAnimations(WebKitWebFrame* frame)
    427 {
    428     Frame* coreFrame = core(frame);
    429     if (!coreFrame)
    430         return;
    431 
    432     return coreFrame->animation()->suspendAnimations();
    433 }
    434 
    435 void DumpRenderTreeSupportGtk::resumeAnimations(WebKitWebFrame* frame)
    436 {
    437     Frame* coreFrame = core(frame);
    438     if (!coreFrame)
    439         return;
    440 
    441     return coreFrame->animation()->resumeAnimations();
    442 }
    443 
    444 void DumpRenderTreeSupportGtk::clearMainFrameName(WebKitWebFrame* frame)
    445 {
    446     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
    447 
    448     core(frame)->tree()->clearName();
    449 }
    450 
    451 AtkObject* DumpRenderTreeSupportGtk::getRootAccessibleElement(WebKitWebFrame* frame)
    452 {
    453     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
    454 
    455 #if HAVE(ACCESSIBILITY)
    456     if (!AXObjectCache::accessibilityEnabled())
    457         AXObjectCache::enableAccessibility();
    458 
    459     WebKitWebFramePrivate* priv = frame->priv;
    460     if (!priv->coreFrame || !priv->coreFrame->document())
    461         return 0;
    462 
    463     AtkObject* wrapper =  priv->coreFrame->document()->axObjectCache()->rootObject()->wrapper();
    464     if (!wrapper)
    465         return 0;
    466 
    467     return wrapper;
    468 #else
    469     return 0;
    470 #endif
    471 }
    472 
    473 AtkObject* DumpRenderTreeSupportGtk::getFocusedAccessibleElement(WebKitWebFrame* frame)
    474 {
    475 #if HAVE(ACCESSIBILITY)
    476     AtkObject* wrapper = getRootAccessibleElement(frame);
    477     if (!wrapper)
    478         return 0;
    479 
    480     return webkit_accessible_get_focused_element(WEBKIT_ACCESSIBLE(wrapper));
    481 #else
    482     return 0;
    483 #endif
    484 }
    485 
    486 void DumpRenderTreeSupportGtk::executeCoreCommandByName(WebKitWebView* webView, const gchar* name, const gchar* value)
    487 {
    488     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
    489     g_return_if_fail(name);
    490     g_return_if_fail(value);
    491 
    492     core(webView)->focusController()->focusedOrMainFrame()->editor()->command(name).execute(value);
    493 }
    494 
    495 bool DumpRenderTreeSupportGtk::isCommandEnabled(WebKitWebView* webView, const gchar* name)
    496 {
    497     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
    498     g_return_val_if_fail(name, FALSE);
    499 
    500     return core(webView)->focusController()->focusedOrMainFrame()->editor()->command(name).isEnabled();
    501 }
    502 
    503 void DumpRenderTreeSupportGtk::setComposition(WebKitWebView* webView, const char* text, int start, int end)
    504 {
    505     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
    506     g_return_if_fail(text);
    507 
    508     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
    509     if (!frame)
    510         return;
    511 
    512     Editor* editor = frame->editor();
    513     if (!editor)
    514         return;
    515     if (!editor->canEdit() && !editor->hasComposition())
    516         return;
    517 
    518     String compositionString = String::fromUTF8(text);
    519     Vector<CompositionUnderline> underlines;
    520     underlines.append(CompositionUnderline(0, compositionString.length(), Color(0, 0, 0), false));
    521     editor->setComposition(compositionString, underlines, start, end);
    522 }
    523 
    524 void DumpRenderTreeSupportGtk::confirmComposition(WebKitWebView* webView, const char* text)
    525 {
    526     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
    527 
    528     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
    529     if (!frame)
    530         return;
    531 
    532     Editor* editor = frame->editor();
    533     if (!editor || (!editor->hasComposition() && !text))
    534         return;
    535 
    536     if (editor->hasComposition()) {
    537         if (text)
    538             editor->confirmComposition(String::fromUTF8(text));
    539         else
    540             editor->confirmComposition();
    541     } else
    542         editor->insertText(String::fromUTF8(text), 0);
    543 }
    544 
    545 bool DumpRenderTreeSupportGtk::firstRectForCharacterRange(WebKitWebView* webView, int location, int length, GdkRectangle* rect)
    546 {
    547     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), false);
    548     g_return_val_if_fail(rect, false);
    549 
    550     if ((location + length < location) && (location + length))
    551         length = 0;
    552 
    553     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
    554     if (!frame)
    555         return false;
    556 
    557     Editor* editor = frame->editor();
    558     if (!editor)
    559         return false;
    560 
    561     Element* selectionRoot = frame->selection()->rootEditableElement();
    562     Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement();
    563     RefPtr<Range> range = TextIterator::rangeFromLocationAndLength(scope, location, length);
    564     if (!range)
    565         return false;
    566 
    567     *rect = editor->firstRectForRange(range.get());
    568 
    569     return true;
    570 }
    571 
    572 bool DumpRenderTreeSupportGtk::selectedRange(WebKitWebView* webView, int* start, int* end)
    573 {
    574     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), false);
    575     g_return_val_if_fail(start, false);
    576     g_return_val_if_fail(end, false);
    577 
    578     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
    579     if (!frame)
    580         return false;
    581 
    582     RefPtr<Range> range = frame->selection()->toNormalizedRange().get();
    583 
    584     Element* selectionRoot = frame->selection()->rootEditableElement();
    585     Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement();
    586 
    587     RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset());
    588     ASSERT(testRange->startContainer() == scope);
    589     *start = TextIterator::rangeLength(testRange.get());
    590 
    591     ExceptionCode ec;
    592     testRange->setEnd(range->endContainer(), range->endOffset(), ec);
    593     ASSERT(testRange->startContainer() == scope);
    594     *end = TextIterator::rangeLength(testRange.get());
    595 
    596     return true;
    597 }
    598 
    599 void DumpRenderTreeSupportGtk::whiteListAccessFromOrigin(const gchar* sourceOrigin, const gchar* destinationProtocol, const gchar* destinationHost, bool allowDestinationSubdomains)
    600 {
    601     SecurityOrigin::addOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains);
    602 }
    603 
    604 void DumpRenderTreeSupportGtk::resetOriginAccessWhiteLists()
    605 {
    606     SecurityOrigin::resetOriginAccessWhitelists();
    607 }
    608 
    609 void DumpRenderTreeSupportGtk::gcCollectJavascriptObjects()
    610 {
    611     gcController().garbageCollectNow();
    612 }
    613 
    614 void DumpRenderTreeSupportGtk::gcCollectJavascriptObjectsOnAlternateThread(bool waitUntilDone)
    615 {
    616     gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone);
    617 }
    618 
    619 unsigned long DumpRenderTreeSupportGtk::gcCountJavascriptObjects()
    620 {
    621     JSC::JSLock lock(JSC::SilenceAssertionsOnly);
    622     return JSDOMWindow::commonJSGlobalData()->heap.objectCount();
    623 }
    624 
    625 void DumpRenderTreeSupportGtk::layoutFrame(WebKitWebFrame* frame)
    626 {
    627     Frame* coreFrame = core(frame);
    628     if (!coreFrame)
    629         return;
    630 
    631     FrameView* view = coreFrame->view();
    632     if (!view)
    633         return;
    634 
    635     view->layout();
    636 }
    637 
    638 // For testing fast/viewport.
    639 void DumpRenderTreeSupportGtk::dumpConfigurationForViewport(WebKitWebView* webView, gint deviceDPI, gint deviceWidth, gint deviceHeight, gint availableWidth, gint availableHeight)
    640 {
    641     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
    642 
    643     ViewportArguments arguments = webView->priv->corePage->mainFrame()->document()->viewportArguments();
    644     ViewportAttributes attrs = computeViewportAttributes(arguments, /* default layout width for non-mobile pages */ 980, deviceWidth, deviceHeight, deviceDPI, IntSize(availableWidth, availableHeight));
    645 
    646     fprintf(stdout, "viewport size %dx%d scale %f with limits [%f, %f] and userScalable %f\n", attrs.layoutSize.width(), attrs.layoutSize.height(), attrs.initialScale, attrs.minimumScale, attrs.maximumScale, attrs.userScalable);
    647 }
    648 
    649 void DumpRenderTreeSupportGtk::clearOpener(WebKitWebFrame* frame)
    650 {
    651     Frame* coreFrame = core(frame);
    652     if (coreFrame)
    653         coreFrame->loader()->setOpener(0);
    654 }
    655 
    656 JSValueRef DumpRenderTreeSupportGtk::shadowRoot(JSContextRef context, JSValueRef value)
    657 {
    658     JSLock lock(SilenceAssertionsOnly);
    659     JSC::ExecState* exec = toJS(context);
    660     Element* element = toElement(toJS(exec, value));
    661     if (!element)
    662         return JSValueMakeNull(context);
    663 
    664     return toRef(exec, toJS(exec, element->shadowRoot()));
    665 }
    666 
    667 unsigned int DumpRenderTreeSupportGtk::workerThreadCount()
    668 {
    669 #if ENABLE(WORKERS)
    670     return WebCore::WorkerThread::workerThreadCount();
    671 #else
    672     return 0;
    673 #endif
    674 }
    675 
    676 bool DumpRenderTreeSupportGtk::webkitWebFrameSelectionHasSpellingMarker(WebKitWebFrame *frame, gint from, gint length)
    677 {
    678     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), FALSE);
    679 
    680     return core(frame)->editor()->selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
    681 }
    682 
    683 bool DumpRenderTreeSupportGtk::findString(WebKitWebView* webView, const gchar* targetString, WebKitFindOptions findOptions)
    684 {
    685     return core(webView)->findString(String::fromUTF8(targetString), findOptions);
    686 }
    687 
    688 double DumpRenderTreeSupportGtk::defaultMinimumTimerInterval()
    689 {
    690     return Settings::defaultMinDOMTimerInterval();
    691 }
    692 
    693 void DumpRenderTreeSupportGtk::setMinimumTimerInterval(WebKitWebView* webView, double interval)
    694 {
    695     core(webView)->settings()->setMinDOMTimerInterval(interval);
    696 }
    697 
    698 static void modifyAccessibilityValue(AtkObject* axObject, bool increment)
    699 {
    700     if (!axObject || !WEBKIT_IS_ACCESSIBLE(axObject))
    701         return;
    702 
    703     AccessibilityObject* coreObject = webkit_accessible_get_accessibility_object(WEBKIT_ACCESSIBLE(axObject));
    704     if (!coreObject)
    705         return;
    706 
    707     if (increment)
    708         coreObject->increment();
    709     else
    710         coreObject->decrement();
    711 }
    712 
    713 void DumpRenderTreeSupportGtk::incrementAccessibilityValue(AtkObject* axObject)
    714 {
    715     modifyAccessibilityValue(axObject, true);
    716 }
    717 
    718 void DumpRenderTreeSupportGtk::decrementAccessibilityValue(AtkObject* axObject)
    719 {
    720     modifyAccessibilityValue(axObject, false);
    721 }
    722 
    723 void DumpRenderTreeSupportGtk::setAutofilled(JSContextRef context, JSValueRef nodeObject, bool autofilled)
    724 {
    725     JSC::ExecState* exec = toJS(context);
    726     Element* element = toElement(toJS(exec, nodeObject));
    727     if (!element)
    728         return;
    729     InputElement* inputElement = element->toInputElement();
    730     if (!inputElement)
    731         return;
    732 
    733     static_cast<HTMLInputElement*>(inputElement)->setAutofilled(autofilled);
    734 }
    735 
    736 void DumpRenderTreeSupportGtk::setValueForUser(JSContextRef context, JSValueRef nodeObject, JSStringRef value)
    737 {
    738     JSC::ExecState* exec = toJS(context);
    739     Element* element = toElement(toJS(exec, nodeObject));
    740     if (!element)
    741         return;
    742     InputElement* inputElement = element->toInputElement();
    743     if (!inputElement)
    744         return;
    745 
    746     size_t bufferSize = JSStringGetMaximumUTF8CStringSize(value);
    747     GOwnPtr<gchar> valueBuffer(static_cast<gchar*>(g_malloc(bufferSize)));
    748     JSStringGetUTF8CString(value, valueBuffer.get(), bufferSize);
    749     inputElement->setValueForUser(String::fromUTF8(valueBuffer.get()));
    750 }
    751 
    752 void DumpRenderTreeSupportGtk::rectangleForSelection(WebKitWebFrame* frame, GdkRectangle* rectangle)
    753 {
    754     Frame* coreFrame = core(frame);
    755     if (!coreFrame)
    756         return;
    757 
    758     IntRect bounds = enclosingIntRect(coreFrame->selection()->bounds());
    759     rectangle->x = bounds.x();
    760     rectangle->y = bounds.y();
    761     rectangle->width = bounds.width();
    762     rectangle->height = bounds.height();
    763 }
    764