[EFL] [DRT] Implement scheduleAsynchronousKeyDown.
[WebKit-https.git] / Source / WebKit / efl / WebCoreSupport / DumpRenderTreeSupportEfl.cpp
1 /*
2     Copyright (C) 2011 ProFUSION embedded systems
3     Copyright (C) 2011 Samsung Electronics
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public License
16     along with this library; see the file COPYING.LIB.  If not, write to
17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19 */
20
21 #include "config.h"
22 #include "DumpRenderTreeSupportEfl.h"
23
24 #include "FrameLoaderClientEfl.h"
25 #include "ewk_private.h"
26
27 #include <AnimationController.h>
28 #include <DocumentLoader.h>
29 #include <Eina.h>
30 #include <Evas.h>
31 #include <FindOptions.h>
32 #include <FloatSize.h>
33 #include <FrameView.h>
34 #include <HTMLInputElement.h>
35 #include <IntRect.h>
36 #include <JSElement.h>
37 #include <PrintContext.h>
38 #include <RenderTreeAsText.h>
39 #include <Settings.h>
40 #include <WebKitMutationObserver.h>
41 #include <bindings/js/GCController.h>
42 #include <history/HistoryItem.h>
43 #include <workers/WorkerThread.h>
44 #include <wtf/OwnArrayPtr.h>
45 #include <wtf/text/AtomicString.h>
46
47 unsigned DumpRenderTreeSupportEfl::activeAnimationsCount(const Evas_Object* ewkFrame)
48 {
49     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
50
51     if (!frame)
52         return 0;
53
54     WebCore::AnimationController* animationController = frame->animation();
55
56     if (!animationController)
57         return 0;
58
59     return animationController->numberOfActiveAnimations(frame->document());
60 }
61
62 void DumpRenderTreeSupportEfl::clearFrameName(Evas_Object* ewkFrame)
63 {
64     if (WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame))
65         frame->tree()->clearName();
66 }
67
68 void DumpRenderTreeSupportEfl::clearOpener(Evas_Object* ewkFrame)
69 {
70     if (WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame))
71         frame->loader()->setOpener(0);
72 }
73
74 String DumpRenderTreeSupportEfl::counterValueByElementId(const Evas_Object* ewkFrame, const char* elementId)
75 {
76     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
77
78     if (!frame)
79         return String();
80
81     WebCore::Element* element = frame->document()->getElementById(elementId);
82
83     if (!element)
84         return String();
85
86     return WebCore::counterValueForElement(element);
87 }
88
89 Eina_List* DumpRenderTreeSupportEfl::frameChildren(const Evas_Object* ewkFrame)
90 {
91     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
92
93     if (!frame)
94         return 0;
95
96     Eina_List* childFrames = 0;
97
98     for (unsigned index = 0; index < frame->tree()->childCount(); index++) {
99         WebCore::Frame *childFrame = frame->tree()->child(index);
100         WebCore::FrameLoaderClientEfl *client = static_cast<WebCore::FrameLoaderClientEfl*>(childFrame->loader()->client());
101
102         if (!client)
103             continue;
104
105         childFrames = eina_list_append(childFrames, client->webFrame());
106     }
107
108     return childFrames;
109 }
110
111 WebCore::Frame* DumpRenderTreeSupportEfl::frameParent(const Evas_Object* ewkFrame)
112 {
113     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
114
115     if (!frame)
116         return 0;
117
118     return frame->tree()->parent();
119 }
120
121 void DumpRenderTreeSupportEfl::layoutFrame(Evas_Object* ewkFrame)
122 {
123     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
124
125     if (!frame)
126         return;
127
128     WebCore::FrameView* frameView = frame->view();
129
130     if (!frameView)
131         return;
132
133     frameView->layout();
134 }
135
136 int DumpRenderTreeSupportEfl::numberOfPages(const Evas_Object* ewkFrame, float pageWidth, float pageHeight)
137 {
138     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
139
140     if (!frame)
141         return 0;
142
143     return WebCore::PrintContext::numberOfPages(frame, WebCore::FloatSize(pageWidth, pageHeight));
144 }
145
146 int DumpRenderTreeSupportEfl::numberOfPagesForElementId(const Evas_Object* ewkFrame, const char* elementId, float pageWidth, float pageHeight)
147 {
148     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
149
150     if (!frame)
151         return 0;
152
153     WebCore::Element *element = frame->document()->getElementById(elementId);
154
155     if (!element)
156         return 0;
157
158     return WebCore::PrintContext::pageNumberForElement(element, WebCore::FloatSize(pageWidth, pageHeight));
159 }
160
161 bool DumpRenderTreeSupportEfl::pauseAnimation(Evas_Object* ewkFrame, const char* name, const char* elementId, double time)
162 {
163     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
164
165     if (!frame)
166         return false;
167
168     WebCore::Element* element = frame->document()->getElementById(elementId);
169
170     if (!element || !element->renderer())
171         return false;
172
173     return frame->animation()->pauseAnimationAtTime(element->renderer(), name, time);
174 }
175
176 bool DumpRenderTreeSupportEfl::pauseTransition(Evas_Object* ewkFrame, const char* name, const char* elementId, double time)
177 {
178     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
179
180     if (!frame)
181         return false;
182
183     WebCore::Element* element = frame->document()->getElementById(elementId);
184
185     if (!element || !element->renderer())
186         return false;
187
188     return frame->animation()->pauseTransitionAtTime(element->renderer(), name, time);
189 }
190
191 unsigned DumpRenderTreeSupportEfl::pendingUnloadEventCount(const Evas_Object* ewkFrame)
192 {
193     if (WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame))
194         return frame->domWindow()->pendingUnloadEventListeners();
195
196     return 0;
197 }
198
199 String DumpRenderTreeSupportEfl::renderTreeDump(Evas_Object* ewkFrame)
200 {
201     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
202
203     if (!frame)
204         return String();
205
206     WebCore::FrameView *frameView = frame->view();
207
208     if (frameView && frameView->layoutPending())
209         frameView->layout();
210
211     return WebCore::externalRepresentation(frame);
212 }
213
214 String DumpRenderTreeSupportEfl::responseMimeType(const Evas_Object* ewkFrame)
215 {
216     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
217
218     if (!frame)
219         return String();
220
221     WebCore::DocumentLoader *documentLoader = frame->loader()->documentLoader();
222
223     if (!documentLoader)
224         return String();
225
226     return documentLoader->responseMIMEType();
227 }
228
229 void DumpRenderTreeSupportEfl::resumeAnimations(Evas_Object* ewkFrame)
230 {
231     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
232
233     if (!frame)
234         return;
235
236     WebCore::AnimationController *animationController = frame->animation();
237     if (animationController)
238         animationController->resumeAnimations();
239 }
240
241 WebCore::IntRect DumpRenderTreeSupportEfl::selectionRectangle(const Evas_Object* ewkFrame)
242 {
243     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
244
245     if (!frame)
246         return WebCore::IntRect();
247
248     return enclosingIntRect(frame->selection()->bounds());
249 }
250
251 // Compare with "WebKit/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm
252 String DumpRenderTreeSupportEfl::suitableDRTFrameName(const Evas_Object* ewkFrame)
253 {
254     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
255
256     if (!frame)
257         return String();
258
259     const String frameName(ewk_frame_name_get(ewkFrame));
260
261     if (ewkFrame == ewk_view_frame_main_get(ewk_frame_view_get(ewkFrame))) {
262         if (!frameName.isEmpty())
263             return String("main frame \"") + frameName + String("\"");
264
265         return String("main frame");
266     }
267
268     if (!frameName.isEmpty())
269         return String("frame \"") + frameName + String("\"");
270
271     return String("frame (anonymous)");
272 }
273
274 void DumpRenderTreeSupportEfl::suspendAnimations(Evas_Object* ewkFrame)
275 {
276     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
277
278     if (!frame)
279         return;
280
281     WebCore::AnimationController *animationController = frame->animation();
282     if (animationController)
283         animationController->suspendAnimations();
284 }
285
286 void DumpRenderTreeSupportEfl::setValueForUser(JSContextRef context, JSValueRef nodeObject, JSStringRef value)
287 {
288     JSC::ExecState* exec = toJS(context);
289     WebCore::Element* element = WebCore::toElement(toJS(exec, nodeObject));
290     if (!element)
291         return;
292     WebCore::HTMLInputElement* inputElement = element->toInputElement();
293     if (!inputElement)
294         return;
295
296     size_t bufferSize = JSStringGetMaximumUTF8CStringSize(value);
297     OwnArrayPtr<char> valueBuffer = adoptArrayPtr(new char[bufferSize]);
298     JSStringGetUTF8CString(value, valueBuffer.get(), bufferSize);
299     inputElement->setValueForUser(String::fromUTF8(valueBuffer.get()));
300 }
301
302 void DumpRenderTreeSupportEfl::setAutofilled(JSContextRef context, JSValueRef nodeObject, bool autofilled)
303 {
304     JSC::ExecState* exec = toJS(context);
305     WebCore::Element* element = WebCore::toElement(toJS(exec, nodeObject));
306     if (!element)
307         return;
308     WebCore::HTMLInputElement* inputElement = element->toInputElement();
309     if (!inputElement)
310         return;
311
312     inputElement->setAutofilled(autofilled);
313 }
314
315 bool DumpRenderTreeSupportEfl::findString(const Evas_Object* ewkView, const char* text, WebCore::FindOptions options)
316 {
317     WebCore::Page* page = EWKPrivate::corePage(ewkView);
318
319     if (!page)
320         return false;
321
322     return page->findString(String::fromUTF8(text), options);
323 }
324
325 void DumpRenderTreeSupportEfl::garbageCollectorCollect()
326 {
327     WebCore::gcController().garbageCollectNow();
328 }
329
330 void DumpRenderTreeSupportEfl::garbageCollectorCollectOnAlternateThread(bool waitUntilDone)
331 {
332     WebCore::gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone);
333 }
334
335 size_t DumpRenderTreeSupportEfl::javaScriptObjectsCount()
336 {
337     return WebCore::JSDOMWindow::commonJSGlobalData()->heap.objectCount();
338 }
339
340 unsigned DumpRenderTreeSupportEfl::workerThreadCount()
341 {
342 #if ENABLE(WORKERS)
343     return WebCore::WorkerThread::workerThreadCount();
344 #else
345     return 0;
346 #endif
347 }
348
349 HistoryItemChildrenVector DumpRenderTreeSupportEfl::childHistoryItems(const Ewk_History_Item* ewkHistoryItem)
350 {
351     WebCore::HistoryItem* historyItem = EWKPrivate::coreHistoryItem(ewkHistoryItem);
352     HistoryItemChildrenVector kids;
353
354     if (!historyItem)
355         return kids;
356
357     const WebCore::HistoryItemVector& children = historyItem->children();
358     const unsigned size = children.size();
359
360     for (unsigned i = 0; i < size; ++i) {
361         Ewk_History_Item* kid = ewk_history_item_new_from_core(children[i].get());
362         kids.append(kid);
363     }
364
365     return kids;
366 }
367
368 String DumpRenderTreeSupportEfl::historyItemTarget(const Ewk_History_Item* ewkHistoryItem)
369 {
370     WebCore::HistoryItem* historyItem = EWKPrivate::coreHistoryItem(ewkHistoryItem);
371
372     if (!historyItem)
373         return String();
374
375     return historyItem->target();
376 }
377
378 bool DumpRenderTreeSupportEfl::isTargetItem(const Ewk_History_Item* ewkHistoryItem)
379 {
380     WebCore::HistoryItem* historyItem = EWKPrivate::coreHistoryItem(ewkHistoryItem);
381
382     if (!historyItem)
383         return false;
384
385     return historyItem->isTargetItem();
386 }
387
388 void DumpRenderTreeSupportEfl::setMockScrollbarsEnabled(bool enable)
389 {
390     WebCore::Settings::setMockScrollbarsEnabled(enable);
391 }
392
393 void DumpRenderTreeSupportEfl::dumpConfigurationForViewport(Evas_Object* ewkView, int deviceDPI, const WebCore::IntSize& deviceSize, const WebCore::IntSize& availableSize)
394 {
395     WebCore::Page* page = EWKPrivate::corePage(ewkView);
396
397     if (!page)
398         return;
399     WebCore::ViewportArguments arguments = page->mainFrame()->document()->viewportArguments();
400     WebCore::ViewportAttributes attributes = computeViewportAttributes(arguments,
401             /* default layout width for non-mobile pages */ 980,
402             deviceSize.width(), deviceSize.height(),
403             deviceDPI,
404             availableSize);
405     restrictMinimumScaleFactorToViewportSize(attributes, availableSize);
406     restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);
407     fprintf(stdout, "viewport size %dx%d scale %f with limits [%f, %f] and userScalable %f\n", attributes.layoutSize.width(), attributes.layoutSize.height(), attributes.initialScale, attributes.minimumScale, attributes.maximumScale, attributes.userScalable);
408 }
409
410 void DumpRenderTreeSupportEfl::deliverAllMutationsIfNecessary()
411 {
412 #if ENABLE(MUTATION_OBSERVERS)
413     WebCore::WebKitMutationObserver::deliverAllMutations();
414 #endif
415 }