[GTK] Clear application cache between tests in DumpRenderTree
[WebKit-https.git] / Source / WebKit / gtk / WebCoreSupport / DumpRenderTreeSupportGtk.cpp
1 /*
2  *  Copyright (C) Research In Motion Limited 2010. All rights reserved.
3  *  Copyright (C) 2010 Joone Hur <joone@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 "AccessibilityObject.h"
28 #include "AnimationController.h"
29 #include "ApplicationCacheStorage.h"
30 #include "CSSComputedStyleDeclaration.h"
31 #include "Chrome.h"
32 #include "ChromeClientGtk.h"
33 #include "DOMWrapperWorld.h"
34 #include "Document.h"
35 #include "EditorClientGtk.h"
36 #include "Element.h"
37 #include "FocusController.h"
38 #include "FrameTree.h"
39 #include "FrameView.h"
40 #include "GCController.h"
41 #include "GeolocationClientMock.h"
42 #include "GeolocationController.h"
43 #include "GeolocationError.h"
44 #include "GeolocationPosition.h"
45 #include "GraphicsContext.h"
46 #include "HTMLInputElement.h"
47 #include "JSCSSStyleDeclaration.h"
48 #include "JSDOMWindow.h"
49 #include "JSDocument.h"
50 #include "JSElement.h"
51 #include "JSLock.h"
52 #include "JSNodeList.h"
53 #include "JSValue.h"
54 #include "MemoryCache.h"
55 #include "MutationObserver.h"
56 #include "NodeList.h"
57 #include "PageGroup.h"
58 #include "PrintContext.h"
59 #include "RenderListItem.h"
60 #include "RenderTreeAsText.h"
61 #include "RenderView.h"
62 #include "ResourceLoadScheduler.h"
63 #include "SchemeRegistry.h"
64 #include "SecurityOrigin.h"
65 #include "SecurityPolicy.h"
66 #include "Settings.h"
67 #include "TextIterator.h"
68 #include "WebKitAccessibleWrapperAtk.h"
69 #include "WorkerThread.h"
70 #include "webkitglobalsprivate.h"
71 #include "webkitwebframe.h"
72 #include "webkitwebframeprivate.h"
73 #include "webkitwebview.h"
74 #include "webkitwebviewprivate.h"
75 #include <JavaScriptCore/APICast.h>
76 #include <wtf/text/WTFString.h>
77
78 using namespace JSC;
79 using namespace WebCore;
80 using namespace WebKit;
81
82 bool DumpRenderTreeSupportGtk::s_drtRun = false;
83 bool DumpRenderTreeSupportGtk::s_linksIncludedInTabChain = true;
84 bool DumpRenderTreeSupportGtk::s_selectTrailingWhitespaceEnabled = false;
85
86 DumpRenderTreeSupportGtk::DumpRenderTreeSupportGtk()
87 {
88 }
89
90 DumpRenderTreeSupportGtk::~DumpRenderTreeSupportGtk()
91 {
92 }
93
94 void DumpRenderTreeSupportGtk::setDumpRenderTreeModeEnabled(bool enabled)
95 {
96     s_drtRun = enabled;
97 }
98
99 bool DumpRenderTreeSupportGtk::dumpRenderTreeModeEnabled()
100 {
101     return s_drtRun;
102 }
103 void DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(bool enabled)
104 {
105     s_linksIncludedInTabChain = enabled;
106 }
107
108 bool DumpRenderTreeSupportGtk::linksIncludedInFocusChain()
109 {
110     return s_linksIncludedInTabChain;
111 }
112
113 void DumpRenderTreeSupportGtk::setSelectTrailingWhitespaceEnabled(bool enabled)
114 {
115     s_selectTrailingWhitespaceEnabled = enabled;
116 }
117
118 bool DumpRenderTreeSupportGtk::selectTrailingWhitespaceEnabled()
119 {
120     return s_selectTrailingWhitespaceEnabled;
121 }
122
123 /**
124  * getFrameChildren:
125  * @frame: a #WebKitWebFrame
126  *
127  * Return value: child frames of @frame
128  */
129 GSList* DumpRenderTreeSupportGtk::getFrameChildren(WebKitWebFrame* frame)
130 {
131     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
132
133     Frame* coreFrame = core(frame);
134     if (!coreFrame)
135         return 0;
136
137     GSList* children = 0;
138     for (Frame* child = coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
139         WebKitWebFrame* kitFrame = kit(child);
140         if (kitFrame)
141           children = g_slist_append(children, kitFrame);
142     }
143
144     return children;
145 }
146
147 /**
148  * getInnerText:
149  * @frame: a #WebKitWebFrame
150  *
151  * Return value: inner text of @frame
152  */
153 CString DumpRenderTreeSupportGtk::getInnerText(WebKitWebFrame* frame)
154 {
155     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), CString(""));
156
157     Frame* coreFrame = core(frame);
158     if (!coreFrame)
159         return CString("");
160
161     FrameView* view = coreFrame->view();
162     if (view && view->layoutPending())
163         view->layout();
164
165     Element* documentElement = coreFrame->document()->documentElement();
166     if (!documentElement)
167         return CString("");
168     return documentElement->innerText().utf8();
169 }
170
171 /**
172  * dumpRenderTree:
173  * @frame: a #WebKitWebFrame
174  *
175  * Return value: Non-recursive render tree dump of @frame
176  */
177 CString DumpRenderTreeSupportGtk::dumpRenderTree(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     return externalRepresentation(coreFrame).utf8();
191 }
192
193 /**
194  * addUserStyleSheet
195  * @frame: a #WebKitWebFrame
196  * @sourceCode: code of a user stylesheet
197  *
198  */
199 void DumpRenderTreeSupportGtk::addUserStyleSheet(WebKitWebFrame* frame, const char* sourceCode, bool allFrames)
200 {
201     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
202
203     Frame* coreFrame = core(frame);
204     if (!coreFrame)
205         return;
206
207     WebKitWebView* webView = getViewFromFrame(frame);
208     Page* page = core(webView);
209     page->group().addUserStyleSheetToWorld(mainThreadNormalWorld(), sourceCode, KURL(), nullptr, nullptr, allFrames ? InjectInAllFrames : InjectInTopFrameOnly); 
210 }
211
212 /**
213  * getPendingUnloadEventCount:
214  * @frame: a #WebKitWebFrame
215  *
216  * Return value: number of pending unload events
217  */
218 guint DumpRenderTreeSupportGtk::getPendingUnloadEventCount(WebKitWebFrame* frame)
219 {
220     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
221
222     return core(frame)->document()->domWindow()->pendingUnloadEventListeners();
223 }
224
225 bool DumpRenderTreeSupportGtk::pauseAnimation(WebKitWebFrame* frame, const char* name, double time, const char* element)
226 {
227     ASSERT(core(frame));
228     Element* coreElement = core(frame)->document()->getElementById(AtomicString(element));
229     if (!coreElement || !coreElement->renderer())
230         return false;
231     return core(frame)->animation()->pauseAnimationAtTime(coreElement->renderer(), AtomicString(name), time);
232 }
233
234 bool DumpRenderTreeSupportGtk::pauseTransition(WebKitWebFrame* frame, const char* name, double time, const char* element)
235 {
236     ASSERT(core(frame));
237     Element* coreElement = core(frame)->document()->getElementById(AtomicString(element));
238     if (!coreElement || !coreElement->renderer())
239         return false;
240     return core(frame)->animation()->pauseTransitionAtTime(coreElement->renderer(), AtomicString(name), time);
241 }
242
243 CString DumpRenderTreeSupportGtk::markerTextForListItem(WebKitWebFrame* frame, JSContextRef context, JSValueRef nodeObject)
244 {
245     JSC::ExecState* exec = toJS(context);
246     Element* element = toElement(toJS(exec, nodeObject));
247     if (!element)
248         return CString();
249
250     return WebCore::markerTextForListItem(element).utf8();
251 }
252
253 unsigned int DumpRenderTreeSupportGtk::numberOfActiveAnimations(WebKitWebFrame* frame)
254 {
255     Frame* coreFrame = core(frame);
256     if (!coreFrame)
257         return 0;
258
259     return coreFrame->animation()->numberOfActiveAnimations(coreFrame->document());
260 }
261
262 void DumpRenderTreeSupportGtk::clearMainFrameName(WebKitWebFrame* frame)
263 {
264     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
265
266     core(frame)->tree()->clearName();
267 }
268
269 AtkObject* DumpRenderTreeSupportGtk::getRootAccessibleElement(WebKitWebFrame* frame)
270 {
271     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
272
273 #if HAVE(ACCESSIBILITY)
274     if (!AXObjectCache::accessibilityEnabled())
275         AXObjectCache::enableAccessibility();
276
277     WebKitWebFramePrivate* priv = frame->priv;
278     if (!priv->coreFrame || !priv->coreFrame->document())
279         return 0;
280
281     AtkObject* wrapper =  priv->coreFrame->document()->axObjectCache()->rootObject()->wrapper();
282     if (!wrapper)
283         return 0;
284
285     return wrapper;
286 #else
287     return 0;
288 #endif
289 }
290
291 AtkObject* DumpRenderTreeSupportGtk::getFocusedAccessibleElement(WebKitWebFrame* frame)
292 {
293 #if HAVE(ACCESSIBILITY)
294     AtkObject* wrapper = getRootAccessibleElement(frame);
295     if (!wrapper)
296         return 0;
297
298     return webkitAccessibleGetFocusedElement(WEBKIT_ACCESSIBLE(wrapper));
299 #else
300     return 0;
301 #endif
302 }
303
304 void DumpRenderTreeSupportGtk::executeCoreCommandByName(WebKitWebView* webView, const gchar* name, const gchar* value)
305 {
306     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
307     g_return_if_fail(name);
308     g_return_if_fail(value);
309
310     core(webView)->focusController()->focusedOrMainFrame()->editor()->command(name).execute(value);
311 }
312
313 bool DumpRenderTreeSupportGtk::isCommandEnabled(WebKitWebView* webView, const gchar* name)
314 {
315     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
316     g_return_val_if_fail(name, FALSE);
317
318     return core(webView)->focusController()->focusedOrMainFrame()->editor()->command(name).isEnabled();
319 }
320
321 void DumpRenderTreeSupportGtk::setComposition(WebKitWebView* webView, const char* text, int start, int length)
322 {
323     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
324     g_return_if_fail(text);
325
326     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
327     if (!frame)
328         return;
329
330     Editor* editor = frame->editor();
331     if (!editor || (!editor->canEdit() && !editor->hasComposition()))
332         return;
333
334     String compositionString = String::fromUTF8(text);
335     Vector<CompositionUnderline> underlines;
336     underlines.append(CompositionUnderline(0, compositionString.length(), Color(0, 0, 0), false));
337     editor->setComposition(compositionString, underlines, start, start + length);
338 }
339
340 bool DumpRenderTreeSupportGtk::hasComposition(WebKitWebView* webView)
341 {
342     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), false);
343     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
344     if (!frame)
345         return false;
346     Editor* editor = frame->editor();
347     if (!editor)
348         return false;
349
350     return editor->hasComposition();
351 }
352
353 bool DumpRenderTreeSupportGtk::compositionRange(WebKitWebView* webView, int* start, int* length)
354 {
355     g_return_val_if_fail(start && length, false);
356     *start = *length = 0;
357
358     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), false);
359     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
360     if (!frame)
361         return false;
362
363     Editor* editor = frame->editor();
364     if (!editor || !editor->hasComposition())
365         return false;
366
367     *start = editor->compositionStart();
368     *length = editor->compositionEnd() - *start;
369     return true;
370 }
371
372 void DumpRenderTreeSupportGtk::confirmComposition(WebKitWebView* webView, const char* text)
373 {
374     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
375
376     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
377     if (!frame)
378         return;
379
380     Editor* editor = frame->editor();
381     if (!editor)
382         return;
383
384     if (!editor->hasComposition()) {
385         editor->insertText(String::fromUTF8(text), 0);
386         return;
387     }
388     if (text) {
389         editor->confirmComposition(String::fromUTF8(text));
390         return;
391     }
392     editor->confirmComposition();
393 }
394
395 void DumpRenderTreeSupportGtk::doCommand(WebKitWebView* webView, const char* command)
396 {
397     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
398     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
399     if (!frame)
400         return;
401
402     Editor* editor = frame->editor();
403     if (!editor)
404         return;
405
406     String commandString(command);
407     // Remove ending : here.
408     if (commandString.endsWith(":", true))
409         commandString = commandString.left(commandString.length() - 1);
410
411     // Make the first char in upper case.
412     String firstChar = commandString.left(1);
413     commandString = commandString.right(commandString.length() - 1);
414     firstChar.makeUpper();
415     commandString.insert(firstChar, 0);
416
417     editor->command(commandString).execute();
418 }
419
420 bool DumpRenderTreeSupportGtk::firstRectForCharacterRange(WebKitWebView* webView, int location, int length, cairo_rectangle_int_t* rect)
421 {
422     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), false);
423     g_return_val_if_fail(rect, false);
424
425     if ((location + length < location) && (location + length))
426         length = 0;
427
428     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
429     if (!frame)
430         return false;
431
432     Editor* editor = frame->editor();
433     if (!editor)
434         return false;
435
436     RefPtr<Range> range = TextIterator::rangeFromLocationAndLength(frame->selection()->rootEditableElementOrDocumentElement(), location, length);
437     if (!range)
438         return false;
439
440     *rect = editor->firstRectForRange(range.get());
441     return true;
442 }
443
444 bool DumpRenderTreeSupportGtk::selectedRange(WebKitWebView* webView, int* start, int* length)
445 {
446     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), false);
447     g_return_val_if_fail(start && length, false);
448
449     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
450     if (!frame)
451         return false;
452
453     RefPtr<Range> range = frame->selection()->toNormalizedRange().get();
454     if (!range)
455         return false;
456
457     Element* selectionRoot = frame->selection()->rootEditableElement();
458     Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement();
459
460     RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset());
461     ASSERT(testRange->startContainer() == scope);
462     *start = TextIterator::rangeLength(testRange.get());
463
464     ExceptionCode ec;
465     testRange->setEnd(range->endContainer(), range->endOffset(), ec);
466     ASSERT(testRange->startContainer() == scope);
467     *length = TextIterator::rangeLength(testRange.get());
468
469     return true;
470 }
471
472 void DumpRenderTreeSupportGtk::setDefersLoading(WebKitWebView* webView, bool defers)
473 {
474     core(webView)->setDefersLoading(defers);
475 }
476
477 void DumpRenderTreeSupportGtk::setSmartInsertDeleteEnabled(WebKitWebView* webView, bool enabled)
478 {
479     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
480     g_return_if_fail(webView);
481
482     WebKit::EditorClient* client = static_cast<WebKit::EditorClient*>(core(webView)->editorClient());
483     client->setSmartInsertDeleteEnabled(enabled);
484 }
485
486 void DumpRenderTreeSupportGtk::forceWebViewPaint(WebKitWebView* webView)
487 {
488     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
489
490     static_cast<WebKit::ChromeClient*>(core(webView)->chrome()->client())->forcePaint();
491 }
492
493 void DumpRenderTreeSupportGtk::whiteListAccessFromOrigin(const gchar* sourceOrigin, const gchar* destinationProtocol, const gchar* destinationHost, bool allowDestinationSubdomains)
494 {
495     SecurityPolicy::addOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains);
496 }
497
498 void DumpRenderTreeSupportGtk::removeWhiteListAccessFromOrigin(const char* sourceOrigin, const char* destinationProtocol, const char* destinationHost, bool allowDestinationSubdomains)
499 {
500     SecurityPolicy::removeOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains);
501 }
502
503 void DumpRenderTreeSupportGtk::resetOriginAccessWhiteLists()
504 {
505     SecurityPolicy::resetOriginAccessWhitelists();
506 }
507
508 void DumpRenderTreeSupportGtk::gcCollectJavascriptObjects()
509 {
510     gcController().garbageCollectNow();
511 }
512
513 void DumpRenderTreeSupportGtk::gcCollectJavascriptObjectsOnAlternateThread(bool waitUntilDone)
514 {
515     gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone);
516 }
517
518 unsigned long DumpRenderTreeSupportGtk::gcCountJavascriptObjects()
519 {
520     JSC::JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
521     return JSDOMWindow::commonJSGlobalData()->heap.objectCount();
522 }
523
524 void DumpRenderTreeSupportGtk::layoutFrame(WebKitWebFrame* frame)
525 {
526     Frame* coreFrame = core(frame);
527     if (!coreFrame)
528         return;
529
530     FrameView* view = coreFrame->view();
531     if (!view)
532         return;
533
534     view->layout();
535 }
536
537 void DumpRenderTreeSupportGtk::clearOpener(WebKitWebFrame* frame)
538 {
539     Frame* coreFrame = core(frame);
540     if (coreFrame)
541         coreFrame->loader()->setOpener(0);
542 }
543
544 unsigned int DumpRenderTreeSupportGtk::workerThreadCount()
545 {
546 #if ENABLE(WORKERS)
547     return WebCore::WorkerThread::workerThreadCount();
548 #else
549     return 0;
550 #endif
551 }
552
553 bool DumpRenderTreeSupportGtk::findString(WebKitWebView* webView, const gchar* targetString, WebKitFindOptions findOptions)
554 {
555     return core(webView)->findString(String::fromUTF8(targetString), findOptions);
556 }
557
558 double DumpRenderTreeSupportGtk::defaultMinimumTimerInterval()
559 {
560     return Settings::defaultMinDOMTimerInterval();
561 }
562
563 void DumpRenderTreeSupportGtk::setMinimumTimerInterval(WebKitWebView* webView, double interval)
564 {
565     core(webView)->settings()->setMinDOMTimerInterval(interval);
566 }
567
568 CString DumpRenderTreeSupportGtk::accessibilityHelpText(AtkObject* axObject)
569 {
570     if (!axObject || !WEBKIT_IS_ACCESSIBLE(axObject))
571         return CString();
572
573     AccessibilityObject* coreObject = webkitAccessibleGetAccessibilityObject(WEBKIT_ACCESSIBLE(axObject));
574     if (!coreObject)
575         return CString();
576
577     return coreObject->helpText().utf8();
578 }
579
580 void DumpRenderTreeSupportGtk::setAutofilled(JSContextRef context, JSValueRef nodeObject, bool autofilled)
581 {
582     JSC::ExecState* exec = toJS(context);
583     Element* element = toElement(toJS(exec, nodeObject));
584     if (!element)
585         return;
586     HTMLInputElement* inputElement = element->toInputElement();
587     if (!inputElement)
588         return;
589
590     inputElement->setAutofilled(autofilled);
591 }
592
593 void DumpRenderTreeSupportGtk::setValueForUser(JSContextRef context, JSValueRef nodeObject, JSStringRef value)
594 {
595     JSC::ExecState* exec = toJS(context);
596     Element* element = toElement(toJS(exec, nodeObject));
597     if (!element)
598         return;
599     HTMLInputElement* inputElement = element->toInputElement();
600     if (!inputElement)
601         return;
602
603     size_t bufferSize = JSStringGetMaximumUTF8CStringSize(value);
604     GOwnPtr<gchar> valueBuffer(static_cast<gchar*>(g_malloc(bufferSize)));
605     JSStringGetUTF8CString(value, valueBuffer.get(), bufferSize);
606     inputElement->setValueForUser(String::fromUTF8(valueBuffer.get()));
607 }
608
609 void DumpRenderTreeSupportGtk::rectangleForSelection(WebKitWebFrame* frame, cairo_rectangle_int_t* rectangle)
610 {
611     Frame* coreFrame = core(frame);
612     if (!coreFrame)
613         return;
614
615     IntRect bounds = enclosingIntRect(coreFrame->selection()->bounds());
616     rectangle->x = bounds.x();
617     rectangle->y = bounds.y();
618     rectangle->width = bounds.width();
619     rectangle->height = bounds.height();
620 }
621
622 bool DumpRenderTreeSupportGtk::shouldClose(WebKitWebFrame* frame)
623 {
624     Frame* coreFrame = core(frame);
625     if (!coreFrame)
626         return true;
627     return coreFrame->loader()->shouldClose();
628 }
629
630 void DumpRenderTreeSupportGtk::scalePageBy(WebKitWebView* webView, float scaleFactor, float x, float y)
631 {
632     core(webView)->setPageScaleFactor(scaleFactor, IntPoint(x, y));
633 }
634
635 void DumpRenderTreeSupportGtk::resetGeolocationClientMock(WebKitWebView* webView)
636 {
637 #if ENABLE(GEOLOCATION)
638     GeolocationClientMock* mock = static_cast<GeolocationClientMock*>(GeolocationController::from(core(webView))->client());
639     mock->reset();
640 #endif
641 }
642
643 void DumpRenderTreeSupportGtk::setMockGeolocationPermission(WebKitWebView* webView, bool allowed)
644 {
645 #if ENABLE(GEOLOCATION)
646     GeolocationClientMock* mock = static_cast<GeolocationClientMock*>(GeolocationController::from(core(webView))->client());
647     mock->setPermission(allowed);
648 #endif
649 }
650
651 void DumpRenderTreeSupportGtk::setMockGeolocationPosition(WebKitWebView* webView, double latitude, double longitude, double accuracy)
652 {
653 #if ENABLE(GEOLOCATION)
654     GeolocationClientMock* mock = static_cast<GeolocationClientMock*>(GeolocationController::from(core(webView))->client());
655
656     double timestamp = g_get_real_time() / 1000000.0;
657     mock->setPosition(GeolocationPosition::create(timestamp, latitude, longitude, accuracy));
658 #endif
659 }
660
661 void DumpRenderTreeSupportGtk::setMockGeolocationError(WebKitWebView* webView, int errorCode, const gchar* errorMessage)
662 {
663 #if ENABLE(GEOLOCATION)
664     GeolocationClientMock* mock = static_cast<GeolocationClientMock*>(GeolocationController::from(core(webView))->client());
665
666     GeolocationError::ErrorCode code;
667     switch (errorCode) {
668     case PositionError::PERMISSION_DENIED:
669         code = GeolocationError::PermissionDenied;
670         break;
671     case PositionError::POSITION_UNAVAILABLE:
672     default:
673         code = GeolocationError::PositionUnavailable;
674         break;
675     }
676
677     mock->setError(GeolocationError::create(code, errorMessage));
678 #endif
679 }
680
681 int DumpRenderTreeSupportGtk::numberOfPendingGeolocationPermissionRequests(WebKitWebView* webView)
682 {
683 #if ENABLE(GEOLOCATION)
684     GeolocationClientMock* mock = static_cast<GeolocationClientMock*>(GeolocationController::from(core(webView))->client());
685     return mock->numberOfPendingPermissionRequests();
686 #endif
687 }
688
689 void DumpRenderTreeSupportGtk::setPageCacheSupportsPlugins(WebKitWebView* webView, bool enabled)
690 {
691     core(webView)->settings()->setPageCacheSupportsPlugins(enabled);
692 }
693
694 void DumpRenderTreeSupportGtk::setCSSGridLayoutEnabled(WebKitWebView* webView, bool enabled)
695 {
696     core(webView)->settings()->setCSSGridLayoutEnabled(enabled);
697 }
698
699 void DumpRenderTreeSupportGtk::setCSSRegionsEnabled(WebKitWebView* webView, bool enabled)
700 {
701     core(webView)->settings()->setCSSRegionsEnabled(enabled);
702 }
703
704 bool DumpRenderTreeSupportGtk::elementDoesAutoCompleteForElementWithId(WebKitWebFrame* frame, JSStringRef id)
705 {
706     Frame* coreFrame = core(frame);
707     if (!coreFrame)
708         return false;
709
710     Document* document = coreFrame->document();
711     ASSERT(document);
712
713     size_t bufferSize = JSStringGetMaximumUTF8CStringSize(id);
714     GOwnPtr<gchar> idBuffer(static_cast<gchar*>(g_malloc(bufferSize)));
715     JSStringGetUTF8CString(id, idBuffer.get(), bufferSize);
716     Node* coreNode = document->getElementById(String::fromUTF8(idBuffer.get()));
717     if (!coreNode || !coreNode->renderer())
718         return false;
719
720     HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(coreNode);
721     if (!inputElement)
722         return false;
723
724     return inputElement->isTextField() && !inputElement->isPasswordField() && inputElement->shouldAutocomplete();
725 }
726
727 JSValueRef DumpRenderTreeSupportGtk::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef nodeObject)
728 {
729     JSC::ExecState* exec = toJS(context);
730     if (!nodeObject)
731         return JSValueMakeUndefined(context);
732
733     JSValue jsValue = toJS(exec, nodeObject);
734     if (!jsValue.inherits(&JSElement::s_info))
735         return JSValueMakeUndefined(context);
736
737     JSElement* jsElement = static_cast<JSElement*>(asObject(jsValue));
738     Element* element = jsElement->impl();
739     RefPtr<CSSComputedStyleDeclaration> style = CSSComputedStyleDeclaration::create(element, true);
740     return toRef(exec, toJS(exec, jsElement->globalObject(), style.get()));
741 }
742
743 void DumpRenderTreeSupportGtk::deliverAllMutationsIfNecessary()
744 {
745 #if ENABLE(MUTATION_OBSERVERS)
746     MutationObserver::deliverAllMutations();
747 #endif
748 }
749
750 void DumpRenderTreeSupportGtk::setDomainRelaxationForbiddenForURLScheme(bool forbidden, const char* urlScheme)
751 {
752     SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(forbidden, String::fromUTF8(urlScheme));
753 }
754
755 void DumpRenderTreeSupportGtk::setSerializeHTTPLoads(bool enabled)
756 {
757     resourceLoadScheduler()->setSerialLoadingEnabled(enabled);
758 }
759
760 void DumpRenderTreeSupportGtk::setTracksRepaints(WebKitWebFrame* frame, bool tracks)
761 {
762     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
763
764     Frame* coreFrame = core(frame);
765     if (coreFrame && coreFrame->view())
766         coreFrame->view()->setTracksRepaints(tracks);
767 }
768
769 bool DumpRenderTreeSupportGtk::isTrackingRepaints(WebKitWebFrame* frame)
770 {
771     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), false);
772
773     Frame* coreFrame = core(frame);
774     if (coreFrame && coreFrame->view())
775         return coreFrame->view()->isTrackingRepaints();
776
777     return false;
778 }
779
780 GSList* DumpRenderTreeSupportGtk::trackedRepaintRects(WebKitWebFrame* frame)
781 {
782     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
783
784     Frame* coreFrame = core(frame);
785     if (!coreFrame || !coreFrame->view())
786         return 0;
787
788     GSList* rects = 0;
789     const Vector<IntRect>& repaintRects = coreFrame->view()->trackedRepaintRects();
790     for (unsigned i = 0; i < repaintRects.size(); i++) {
791         GdkRectangle* rect = g_new0(GdkRectangle, 1);
792         rect->x = repaintRects[i].x();
793         rect->y = repaintRects[i].y();
794         rect->width = repaintRects[i].width();
795         rect->height = repaintRects[i].height();
796         rects = g_slist_append(rects, rect);
797     }
798
799     return rects;
800 }
801
802 void DumpRenderTreeSupportGtk::resetTrackedRepaints(WebKitWebFrame* frame)
803 {
804     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
805
806     Frame* coreFrame = core(frame);
807     if (coreFrame && coreFrame->view())
808         coreFrame->view()->resetTrackedRepaints();
809 }
810
811 void DumpRenderTreeSupportGtk::clearMemoryCache()
812 {
813     memoryCache()->evictResources();
814 }
815
816 void DumpRenderTreeSupportGtk::clearApplicationCache()
817 {
818     cacheStorage().empty();
819     cacheStorage().vacuumDatabaseFile();
820 }