Source/WebCore: Moved markerTextForListItem from TestRunner to Internals
[WebKit-https.git] / Source / WebKit / efl / WebCoreSupport / DumpRenderTreeSupportEfl.cpp
1 /*
2     Copyright (C) 2011 ProFUSION embedded systems
3     Copyright (C) 2011 Samsung Electronics
4     Copyright (C) 2012 Intel Corporation. All rights reserved.
5
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Library General Public
8     License as published by the Free Software Foundation; either
9     version 2 of the License, or (at your option) any later version.
10
11     This library is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14     Library General Public License for more details.
15
16     You should have received a copy of the GNU Library General Public License
17     along with this library; see the file COPYING.LIB.  If not, write to
18     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19     Boston, MA 02110-1301, USA.
20 */
21
22 #include "config.h"
23 #include "DumpRenderTreeSupportEfl.h"
24
25 #include "FrameLoaderClientEfl.h"
26 #include "ewk_frame_private.h"
27 #include "ewk_history_private.h"
28 #include "ewk_private.h"
29 #include "ewk_view_private.h"
30
31 #include <APICast.h>
32 #include <AnimationController.h>
33 #include <CSSComputedStyleDeclaration.h>
34 #include <DocumentLoader.h>
35 #include <EditorClientEfl.h>
36 #include <Eina.h>
37 #include <Evas.h>
38 #include <FindOptions.h>
39 #include <FloatSize.h>
40 #include <FocusController.h>
41 #include <FrameView.h>
42 #include <HTMLInputElement.h>
43 #include <InspectorController.h>
44 #include <IntRect.h>
45 #include <JSCSSStyleDeclaration.h>
46 #include <JSElement.h>
47 #include <JavaScriptCore/OpaqueJSString.h>
48 #include <MemoryCache.h>
49 #include <MutationObserver.h>
50 #include <PageGroup.h>
51 #include <PrintContext.h>
52 #include <RenderTreeAsText.h>
53 #include <ResourceLoadScheduler.h>
54 #include <RuntimeEnabledFeatures.h>
55 #include <SchemeRegistry.h>
56 #include <ScriptValue.h>
57 #include <Settings.h>
58 #include <TextIterator.h>
59 #include <bindings/js/GCController.h>
60 #include <history/HistoryItem.h>
61 #include <wtf/HashMap.h>
62 #include <wtf/UnusedParam.h>
63
64 #if ENABLE(GEOLOCATION)
65 #include <GeolocationClientMock.h>
66 #include <GeolocationController.h>
67 #include <GeolocationError.h>
68 #include <GeolocationPosition.h>
69 #include <wtf/CurrentTime.h>
70 #endif
71
72 #if HAVE(ACCESSIBILITY)
73 #include "AXObjectCache.h"
74 #include "AccessibilityObject.h"
75 #include "WebKitAccessibleWrapperAtk.h"
76 #endif
77
78 #define DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, ...) \
79     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);  \
80     if (!frame)                                               \
81         return __VA_ARGS__;
82
83 #define DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, ...) \
84     WebCore::Page* page = EWKPrivate::corePage(ewkView);  \
85     if (!page)                                            \
86         return __VA_ARGS__;
87
88 bool DumpRenderTreeSupportEfl::s_drtRun = false;
89
90 void DumpRenderTreeSupportEfl::setDumpRenderTreeModeEnabled(bool enabled)
91 {
92     s_drtRun = enabled;
93 }
94
95 bool DumpRenderTreeSupportEfl::dumpRenderTreeModeEnabled()
96 {
97     return s_drtRun;
98 }
99
100 bool DumpRenderTreeSupportEfl::callShouldCloseOnWebView(Evas_Object* ewkFrame)
101 {
102     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, false);
103
104     return frame->loader()->shouldClose();
105 }
106
107 void DumpRenderTreeSupportEfl::clearFrameName(Evas_Object* ewkFrame)
108 {
109     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame);
110
111     frame->tree()->clearName();
112 }
113
114 void DumpRenderTreeSupportEfl::clearOpener(Evas_Object* ewkFrame)
115 {
116     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame);
117
118     frame->loader()->setOpener(0);
119 }
120
121 String DumpRenderTreeSupportEfl::layerTreeAsText(const Evas_Object* ewkFrame)
122 {
123     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, String());
124
125     return frame->layerTreeAsText();
126 }
127
128 bool DumpRenderTreeSupportEfl::elementDoesAutoCompleteForElementWithId(const Evas_Object* ewkFrame, const String& elementId)
129 {
130     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, false);
131
132     WebCore::Document* document = frame->document();
133     ASSERT(document);
134
135     WebCore::HTMLInputElement* inputElement = static_cast<WebCore::HTMLInputElement*>(document->getElementById(elementId));
136
137     if (!inputElement)
138         return false;
139
140     return inputElement->isTextField() && !inputElement->isPasswordField() && inputElement->shouldAutocomplete();
141 }
142
143 Eina_List* DumpRenderTreeSupportEfl::frameChildren(const Evas_Object* ewkFrame)
144 {
145     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, 0);
146
147     Eina_List* childFrames = 0;
148
149     for (unsigned index = 0; index < frame->tree()->childCount(); index++) {
150         WebCore::Frame *childFrame = frame->tree()->child(index);
151         WebCore::FrameLoaderClientEfl *client = static_cast<WebCore::FrameLoaderClientEfl*>(childFrame->loader()->client());
152
153         if (!client)
154             continue;
155
156         childFrames = eina_list_append(childFrames, client->webFrame());
157     }
158
159     return childFrames;
160 }
161
162 WebCore::Frame* DumpRenderTreeSupportEfl::frameParent(const Evas_Object* ewkFrame)
163 {
164     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, 0);
165
166     return frame->tree()->parent();
167 }
168
169 void DumpRenderTreeSupportEfl::layoutFrame(Evas_Object* ewkFrame)
170 {
171     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame);
172
173     if (!frame->view())
174         return;
175
176     frame->view()->layout();
177 }
178
179 unsigned DumpRenderTreeSupportEfl::pendingUnloadEventCount(const Evas_Object* ewkFrame)
180 {
181     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, 0);
182
183     return frame->document()->domWindow()->pendingUnloadEventListeners();
184 }
185
186 String DumpRenderTreeSupportEfl::renderTreeDump(Evas_Object* ewkFrame)
187 {
188     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, String());
189
190     WebCore::FrameView *frameView = frame->view();
191
192     if (frameView && frameView->layoutPending())
193         frameView->layout();
194
195     return WebCore::externalRepresentation(frame);
196 }
197
198 String DumpRenderTreeSupportEfl::responseMimeType(const Evas_Object* ewkFrame)
199 {
200     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, String());
201
202     WebCore::DocumentLoader *documentLoader = frame->loader()->documentLoader();
203
204     if (!documentLoader)
205         return String();
206
207     return documentLoader->responseMIMEType();
208 }
209
210 WebCore::IntRect DumpRenderTreeSupportEfl::selectionRectangle(const Evas_Object* ewkFrame)
211 {
212     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, WebCore::IntRect());
213
214     return enclosingIntRect(frame->selection()->bounds());
215 }
216
217 // Compare with "WebKit/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm
218 String DumpRenderTreeSupportEfl::suitableDRTFrameName(const Evas_Object* ewkFrame)
219 {
220     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, String());
221
222     const String frameName(ewk_frame_name_get(ewkFrame));
223
224     if (ewkFrame == ewk_view_frame_main_get(ewk_frame_view_get(ewkFrame))) {
225         if (!frameName.isEmpty())
226             return String("main frame \"") + frameName + String("\"");
227
228         return String("main frame");
229     }
230
231     if (!frameName.isEmpty())
232         return String("frame \"") + frameName + String("\"");
233
234     return String("frame (anonymous)");
235 }
236
237 void DumpRenderTreeSupportEfl::setValueForUser(JSContextRef context, JSValueRef nodeObject, const String& value)
238 {
239     JSC::ExecState* exec = toJS(context);
240     WebCore::Element* element = WebCore::toElement(toJS(exec, nodeObject));
241     if (!element)
242         return;
243     WebCore::HTMLInputElement* inputElement = element->toInputElement();
244     if (!inputElement)
245         return;
246
247     inputElement->setValueForUser(value);
248 }
249
250 void DumpRenderTreeSupportEfl::setDefersLoading(Evas_Object* ewkView, bool defers)
251 {
252     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
253
254     page->setDefersLoading(defers);
255 }
256
257 void DumpRenderTreeSupportEfl::setLoadsSiteIconsIgnoringImageLoadingSetting(Evas_Object* ewkView, bool loadsSiteIconsIgnoringImageLoadingPreferences)
258 {
259     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
260
261     page->settings()->setLoadsSiteIconsIgnoringImageLoadingSetting(loadsSiteIconsIgnoringImageLoadingPreferences);
262 }
263
264 void DumpRenderTreeSupportEfl::setMinimumLogicalFontSize(Evas_Object* ewkView, int size)
265 {
266     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
267
268     page->settings()->setMinimumLogicalFontSize(size);
269 }
270
271 void DumpRenderTreeSupportEfl::addUserScript(const Evas_Object* ewkView, const String& sourceCode, bool runAtStart, bool allFrames)
272 {
273     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
274
275     page->group().addUserScriptToWorld(WebCore::mainThreadNormalWorld(), sourceCode, WebCore::KURL(),
276                                        Vector<String>(), Vector<String>(), runAtStart ? WebCore::InjectAtDocumentStart : WebCore::InjectAtDocumentEnd,
277                                        allFrames ? WebCore::InjectInAllFrames : WebCore::InjectInTopFrameOnly);
278 }
279
280 void DumpRenderTreeSupportEfl::clearUserScripts(const Evas_Object* ewkView)
281 {
282     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
283
284     page->group().removeUserScriptsFromWorld(WebCore::mainThreadNormalWorld());
285 }
286
287 void DumpRenderTreeSupportEfl::addUserStyleSheet(const Evas_Object* ewkView, const String& sourceCode, bool allFrames)
288 {
289     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
290
291     page->group().addUserStyleSheetToWorld(WebCore::mainThreadNormalWorld(), sourceCode, WebCore::KURL(), Vector<String>(), Vector<String>(), allFrames ? WebCore::InjectInAllFrames : WebCore::InjectInTopFrameOnly);
292 }
293
294 void DumpRenderTreeSupportEfl::clearUserStyleSheets(const Evas_Object* ewkView)
295 {
296     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
297
298     page->group().removeUserStyleSheetsFromWorld(WebCore::mainThreadNormalWorld());
299 }
300
301 void DumpRenderTreeSupportEfl::executeCoreCommandByName(const Evas_Object* ewkView, const char* name, const char* value)
302 {
303     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
304
305     page->focusController()->focusedOrMainFrame()->editor()->command(name).execute(value);
306 }
307
308 bool DumpRenderTreeSupportEfl::findString(const Evas_Object* ewkView, const String& text, WebCore::FindOptions options)
309 {
310     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, false);
311
312     return page->findString(text, options);
313 }
314
315 void DumpRenderTreeSupportEfl::setCSSGridLayoutEnabled(const Evas_Object* ewkView, bool enabled)
316 {
317     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
318
319     page->settings()->setCSSGridLayoutEnabled(enabled);
320 }
321
322 void DumpRenderTreeSupportEfl::setCSSRegionsEnabled(const Evas_Object* ewkView, bool enabled)
323 {
324     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
325
326     WebCore::RuntimeEnabledFeatures::setCSSRegionsEnabled(enabled);
327 }
328
329 void DumpRenderTreeSupportEfl::setSeamlessIFramesEnabled(bool enabled)
330 {
331     WebCore::RuntimeEnabledFeatures::setSeamlessIFramesEnabled(enabled);
332 }
333
334 bool DumpRenderTreeSupportEfl::isCommandEnabled(const Evas_Object* ewkView, const char* name)
335 {
336     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, false);
337
338     return page->focusController()->focusedOrMainFrame()->editor()->command(name).isEnabled();
339 }
340
341 void DumpRenderTreeSupportEfl::setSmartInsertDeleteEnabled(Evas_Object* ewkView, bool enabled)
342 {
343     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
344
345     WebCore::EditorClientEfl* editorClient = static_cast<WebCore::EditorClientEfl*>(page->editorClient());
346     if (!editorClient)
347         return;
348
349     editorClient->setSmartInsertDeleteEnabled(enabled);
350 }
351
352 void DumpRenderTreeSupportEfl::setSelectTrailingWhitespaceEnabled(Evas_Object* ewkView, bool enabled)
353 {
354     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
355
356     WebCore::EditorClientEfl* editorClient = static_cast<WebCore::EditorClientEfl*>(page->editorClient());
357     if (!editorClient)
358         return;
359
360     editorClient->setSelectTrailingWhitespaceEnabled(enabled);
361 }
362
363 void DumpRenderTreeSupportEfl::forceLayout(Evas_Object* ewkFrame)
364 {
365     ewk_frame_force_layout(ewkFrame);
366 }
367
368 void DumpRenderTreeSupportEfl::setTracksRepaints(Evas_Object* ewkFrame, bool enabled)
369 {
370     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame);
371
372     if (frame->view())
373         frame->view()->setTracksRepaints(enabled);
374 }
375
376 void DumpRenderTreeSupportEfl::resetTrackedRepaints(Evas_Object* ewkFrame)
377 {
378     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame);
379
380     if (frame->view())
381         frame->view()->resetTrackedRepaints();
382 }
383
384 bool DumpRenderTreeSupportEfl::isTrackingRepaints(const Evas_Object* ewkFrame)
385 {
386     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, false);
387
388     if (!frame->view())
389         return false;
390
391     return frame->view()->isTrackingRepaints();
392 }
393
394 Eina_List* DumpRenderTreeSupportEfl::trackedRepaintRects(const Evas_Object* ewkFrame)
395 {
396     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, 0);
397
398     if (!frame->view())
399         return 0;
400
401     const Vector<WebCore::IntRect>& repaintRects = frame->view()->trackedRepaintRects();
402     size_t count = repaintRects.size();
403     Eina_List* rectList = 0;
404
405     for (size_t i = 0; i < count; ++i) {
406         Eina_Rectangle* rect = eina_rectangle_new(repaintRects[i].x(), repaintRects[i].y(), repaintRects[i].width(), repaintRects[i].height());
407         rectList = eina_list_append(rectList, rect);
408     }
409
410     return rectList;
411 }
412
413 void DumpRenderTreeSupportEfl::garbageCollectorCollect()
414 {
415     WebCore::gcController().garbageCollectNow();
416 }
417
418 void DumpRenderTreeSupportEfl::garbageCollectorCollectOnAlternateThread(bool waitUntilDone)
419 {
420     WebCore::gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone);
421 }
422
423 size_t DumpRenderTreeSupportEfl::javaScriptObjectsCount()
424 {
425     return WebCore::JSDOMWindow::commonJSGlobalData()->heap.objectCount();
426 }
427
428 void DumpRenderTreeSupportEfl::setDeadDecodedDataDeletionInterval(double interval)
429 {
430     WebCore::memoryCache()->setDeadDecodedDataDeletionInterval(interval);
431 }
432
433 HistoryItemChildrenVector DumpRenderTreeSupportEfl::childHistoryItems(const Ewk_History_Item* ewkHistoryItem)
434 {
435     WebCore::HistoryItem* historyItem = EWKPrivate::coreHistoryItem(ewkHistoryItem);
436     HistoryItemChildrenVector kids;
437
438     if (!historyItem)
439         return kids;
440
441     const WebCore::HistoryItemVector& children = historyItem->children();
442     const unsigned size = children.size();
443
444     for (unsigned i = 0; i < size; ++i) {
445         Ewk_History_Item* kid = ewk_history_item_new_from_core(children[i].get());
446         kids.append(kid);
447     }
448
449     return kids;
450 }
451
452 String DumpRenderTreeSupportEfl::historyItemTarget(const Ewk_History_Item* ewkHistoryItem)
453 {
454     WebCore::HistoryItem* historyItem = EWKPrivate::coreHistoryItem(ewkHistoryItem);
455
456     if (!historyItem)
457         return String();
458
459     return historyItem->target();
460 }
461
462 bool DumpRenderTreeSupportEfl::isTargetItem(const Ewk_History_Item* ewkHistoryItem)
463 {
464     WebCore::HistoryItem* historyItem = EWKPrivate::coreHistoryItem(ewkHistoryItem);
465
466     if (!historyItem)
467         return false;
468
469     return historyItem->isTargetItem();
470 }
471
472 void DumpRenderTreeSupportEfl::evaluateInWebInspector(const Evas_Object* ewkView, long callId, const String& script)
473 {
474 #if ENABLE(INSPECTOR)
475     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
476
477     if (page->inspectorController())
478         page->inspectorController()->evaluateForTestInFrontend(callId, script);
479 #else
480     UNUSED_PARAM(ewkView);
481     UNUSED_PARAM(callId);
482     UNUSED_PARAM(script);
483 #endif
484 }
485
486 void DumpRenderTreeSupportEfl::evaluateScriptInIsolatedWorld(const Evas_Object* ewkFrame, int worldID, JSObjectRef globalObject, const String& script)
487 {
488     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame);
489
490     // Comment from mac: Start off with some guess at a frame and a global object, we'll try to do better...!
491     WebCore::JSDOMWindow* anyWorldGlobalObject = frame->script()->globalObject(WebCore::mainThreadNormalWorld());
492
493     // Comment from mac: The global object is probably a shell object? - if so, we know how to use this!
494     JSC::JSObject* globalObjectObj = toJS(globalObject);
495     if (!strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell"))
496         anyWorldGlobalObject = static_cast<WebCore::JSDOMWindowShell*>(globalObjectObj)->window();
497
498     // Comment from mac: Get the frame from the global object we've settled on.
499     WebCore::Frame* globalFrame = anyWorldGlobalObject->impl()->frame();
500     if (!globalFrame)
501         return;
502
503     WebCore::ScriptController* proxy = globalFrame->script();
504     if (!proxy)
505         return;
506
507     static WTF::HashMap<int, WTF::RefPtr<WebCore::DOMWrapperWorld > > worldMap;
508
509     WTF::RefPtr<WebCore::DOMWrapperWorld> scriptWorld;
510     if (!worldID)
511         scriptWorld = WebCore::ScriptController::createWorld();
512     else {
513         WTF::HashMap<int, RefPtr<WebCore::DOMWrapperWorld > >::const_iterator it = worldMap.find(worldID);
514         if (it != worldMap.end())
515             scriptWorld = (*it).value;
516         else {
517             scriptWorld = WebCore::ScriptController::createWorld();
518             worldMap.set(worldID, scriptWorld);
519         }
520     }
521
522     // The code below is only valid for JSC, V8 specific code is to be added
523     // when V8 will be supported in EFL port. See Qt implemenation.
524     proxy->executeScriptInWorld(scriptWorld.get(), script, true);
525 }
526
527 JSGlobalContextRef DumpRenderTreeSupportEfl::globalContextRefForFrame(const Evas_Object* ewkFrame)
528 {
529     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, 0);
530
531     return toGlobalRef(frame->script()->globalObject(WebCore::mainThreadNormalWorld())->globalExec());
532 }
533
534 void DumpRenderTreeSupportEfl::setMockScrollbarsEnabled(bool enable)
535 {
536     WebCore::Settings::setMockScrollbarsEnabled(enable);
537 }
538
539 void DumpRenderTreeSupportEfl::deliverAllMutationsIfNecessary()
540 {
541     WebCore::MutationObserver::deliverAllMutations();
542 }
543
544 void DumpRenderTreeSupportEfl::setInteractiveFormValidationEnabled(Evas_Object* ewkView, bool enabled)
545 {
546     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
547
548     page->settings()->setInteractiveFormValidationEnabled(enabled);
549 }
550
551 void DumpRenderTreeSupportEfl::setValidationMessageTimerMagnification(Evas_Object* ewkView, int value)
552 {
553     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
554
555     page->settings()->setValidationMessageTimerMagnification(value);
556 }
557
558 JSValueRef DumpRenderTreeSupportEfl::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef value)
559 {
560     if (!value)
561         return JSValueMakeUndefined(context);
562
563     JSC::ExecState* exec = toJS(context);
564     JSC::JSValue jsValue = toJS(exec, value);
565     if (!jsValue.inherits(&WebCore::JSElement::s_info))
566         return JSValueMakeUndefined(context);
567
568     WebCore::JSElement* jsElement = static_cast<WebCore::JSElement*>(asObject(jsValue));
569     WebCore::Element* element = jsElement->impl();
570     RefPtr<WebCore::CSSComputedStyleDeclaration> style = WebCore::CSSComputedStyleDeclaration::create(element, true);
571     return toRef(exec, toJS(exec, jsElement->globalObject(), style.get()));
572 }
573
574 void DumpRenderTreeSupportEfl::setAuthorAndUserStylesEnabled(Evas_Object* ewkView, bool enabled)
575 {
576     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
577
578     page->settings()->setAuthorAndUserStylesEnabled(enabled);
579 }
580
581 void DumpRenderTreeSupportEfl::setSerializeHTTPLoads(bool enabled)
582 {
583     WebCore::resourceLoadScheduler()->setSerialLoadingEnabled(enabled);
584 }
585
586 void DumpRenderTreeSupportEfl::setShouldTrackVisitedLinks(bool shouldTrack)
587 {
588     WebCore::PageGroup::setShouldTrackVisitedLinks(shouldTrack);
589 }
590
591 void DumpRenderTreeSupportEfl::setComposition(Evas_Object* ewkView, const char* text, int start, int length)
592 {
593     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
594
595     if (!page->focusController() || !page->focusController()->focusedOrMainFrame())
596         return;
597
598     WebCore::Editor* editor = page->focusController()->focusedOrMainFrame()->editor();
599     if (!editor || (!editor->canEdit() && !editor->hasComposition()))
600         return;
601
602     const String compositionString = String::fromUTF8(text);
603     Vector<WebCore::CompositionUnderline> underlines;
604     underlines.append(WebCore::CompositionUnderline(0, compositionString.length(), WebCore::Color(0, 0, 0), false));
605     editor->setComposition(compositionString, underlines, start, start + length);
606 }
607
608 bool DumpRenderTreeSupportEfl::hasComposition(const Evas_Object* ewkView)
609 {
610     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, false);
611
612     if (!page->focusController() || !page->focusController()->focusedOrMainFrame())
613         return false;
614
615     const WebCore::Editor* editor = page->focusController()->focusedOrMainFrame()->editor();
616     if (!editor)
617         return false;
618
619     return editor->hasComposition();
620 }
621
622 bool DumpRenderTreeSupportEfl::compositionRange(Evas_Object* ewkView, int* start, int* length)
623 {
624     *start = *length = 0;
625
626     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, false);
627
628     if (!page->focusController() || !page->focusController()->focusedOrMainFrame())
629         return false;
630
631     WebCore::Editor* editor = page->focusController()->focusedOrMainFrame()->editor();
632     if (!editor || !editor->hasComposition())
633         return false;
634
635     *start = editor->compositionStart();
636     *length = editor->compositionEnd() - *start;
637     return true;
638 }
639
640 void DumpRenderTreeSupportEfl::confirmComposition(Evas_Object* ewkView, const char* text)
641 {
642     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
643
644     if (!page->focusController() || !page->focusController()->focusedOrMainFrame())
645         return;
646
647     WebCore::Editor* editor = page->focusController()->focusedOrMainFrame()->editor();
648     if (!editor)
649         return;
650
651     if (!editor->hasComposition()) {
652         editor->insertText(String::fromUTF8(text), 0);
653         return;
654     }
655
656     if (text) {
657         editor->confirmComposition(String::fromUTF8(text));
658         return;
659     }
660     editor->confirmComposition();
661 }
662
663 WebCore::IntRect DumpRenderTreeSupportEfl::firstRectForCharacterRange(Evas_Object* ewkView, int location, int length)
664 {
665     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, WebCore::IntRect());
666
667     if (!page->focusController() || !page->focusController()->focusedOrMainFrame() || !page->focusController()->focusedOrMainFrame()->editor())
668         return WebCore::IntRect();
669
670     if ((location + length < location) && (location + length))
671         length = 0;
672
673     WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
674     WebCore::Editor* editor = frame->editor();
675
676     RefPtr<WebCore::Range> range = WebCore::TextIterator::rangeFromLocationAndLength(frame->selection()->rootEditableElementOrDocumentElement(), location, length);
677     if (!range)
678         return WebCore::IntRect();
679
680     return editor->firstRectForRange(range.get());
681 }
682
683 bool DumpRenderTreeSupportEfl::selectedRange(Evas_Object* ewkView, int* start, int* length)
684 {
685     if (!(start && length))
686         return false;
687
688     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, false);
689
690     if (!page->focusController() || !page->focusController()->focusedOrMainFrame())
691         return false;
692
693     WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
694     RefPtr<WebCore::Range> range = frame->selection()->toNormalizedRange().get();
695     if (!range)
696         return false;
697
698     WebCore::Element* selectionRoot = frame->selection()->rootEditableElement();
699     WebCore::Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement();
700
701     RefPtr<WebCore::Range> testRange = WebCore::Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset());
702     *start = WebCore::TextIterator::rangeLength(testRange.get());
703
704     WebCore::ExceptionCode ec;
705     testRange->setEnd(range->endContainer(), range->endOffset(), ec);
706     *length = WebCore::TextIterator::rangeLength(testRange.get());
707
708     return true;
709 }
710
711 void DumpRenderTreeSupportEfl::setDomainRelaxationForbiddenForURLScheme(bool forbidden, const String& scheme)
712 {
713     WebCore::SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(forbidden, scheme);
714 }
715
716 void DumpRenderTreeSupportEfl::resetGeolocationClientMock(const Evas_Object* ewkView)
717 {
718 #if ENABLE(GEOLOCATION)
719     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
720
721     WebCore::GeolocationClientMock* mock = static_cast<WebCore::GeolocationClientMock*>(WebCore::GeolocationController::from(page)->client());
722     mock->reset();
723 #else
724     UNUSED_PARAM(ewkView);
725 #endif
726 }
727
728 void DumpRenderTreeSupportEfl::setMockGeolocationPermission(const Evas_Object* ewkView, bool allowed)
729 {
730 #if ENABLE(GEOLOCATION)
731     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
732
733     WebCore::GeolocationClientMock* mock = static_cast<WebCore::GeolocationClientMock*>(WebCore::GeolocationController::from(page)->client());
734     mock->setPermission(allowed);
735 #else
736     UNUSED_PARAM(ewkView);
737     UNUSED_PARAM(allowed);
738 #endif
739 }
740
741 void DumpRenderTreeSupportEfl::setMockGeolocationPosition(const Evas_Object* ewkView, double latitude, double longitude, double accuracy, bool canProvideAltitude, double altitude, bool canProvideAltitudeAccuracy, double altitudeAccuracy, bool canProvideHeading, double heading, bool canProvideSpeed, double speed)
742 {
743 #if ENABLE(GEOLOCATION)
744     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
745
746     WebCore::GeolocationClientMock* mock = static_cast<WebCore::GeolocationClientMock*>(WebCore::GeolocationController::from(page)->client());
747     mock->setPosition(WebCore::GeolocationPosition::create(currentTime(), latitude, longitude, accuracy, canProvideAltitude, altitude, canProvideAltitudeAccuracy, altitudeAccuracy, canProvideHeading, heading, canProvideSpeed, speed));
748 #else
749     UNUSED_PARAM(ewkView);
750     UNUSED_PARAM(latitude);
751     UNUSED_PARAM(longitude);
752     UNUSED_PARAM(accuracy);
753     UNUSED_PARAM(canProvideAltitude);
754     UNUSED_PARAM(altitude);
755     UNUSED_PARAM(canProvideAltitudeAccuracy);
756     UNUSED_PARAM(altitudeAccuracy);
757     UNUSED_PARAM(canProvideHeading);
758     UNUSED_PARAM(heading);
759     UNUSED_PARAM(canProvideSpeed);
760     UNUSED_PARAM(speed);
761 #endif
762 }
763
764 void DumpRenderTreeSupportEfl::setMockGeolocationPositionUnavailableError(const Evas_Object* ewkView, const char* errorMessage)
765 {
766 #if ENABLE(GEOLOCATION)
767     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page);
768
769     WebCore::GeolocationClientMock* mock = static_cast<WebCore::GeolocationClientMock*>(WebCore::GeolocationController::from(page)->client());
770     mock->setPositionUnavailableError(errorMessage);
771 #else
772     UNUSED_PARAM(ewkView);
773     UNUSED_PARAM(errorMessage);
774 #endif
775 }
776
777 int DumpRenderTreeSupportEfl::numberOfPendingGeolocationPermissionRequests(const Evas_Object* ewkView)
778 {
779 #if ENABLE(GEOLOCATION)
780     DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, -1);
781
782     WebCore::GeolocationClientMock* mock = static_cast<WebCore::GeolocationClientMock*>(WebCore::GeolocationController::from(page)->client());
783     return mock->numberOfPendingPermissionRequests();
784 #else
785     UNUSED_PARAM(ewkView);
786     return 0;
787 #endif
788 }
789
790 #if HAVE(ACCESSIBILITY)
791 AtkObject* DumpRenderTreeSupportEfl::rootAccessibleElement(const Evas_Object* ewkFrame)
792 {
793     DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, 0);
794
795     if (!WebCore::AXObjectCache::accessibilityEnabled())
796         WebCore::AXObjectCache::enableAccessibility();
797
798     if (!frame->document())
799         return 0;
800
801     AtkObject* wrapper = frame->document()->axObjectCache()->rootObject()->wrapper();
802     if (!wrapper)
803         return 0;
804
805     return wrapper;
806 }
807
808 AtkObject* DumpRenderTreeSupportEfl::focusedAccessibleElement(const Evas_Object* ewkFrame)
809 {
810     AtkObject* wrapper = rootAccessibleElement(ewkFrame);
811     if (!wrapper)
812         return 0;
813
814     return webkitAccessibleGetFocusedElement(WEBKIT_ACCESSIBLE(wrapper));
815 }
816 #endif