[EFL][DRT] Implement setValueForUser and setAutofilled.
[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 <bindings/js/GCController.h>
41 #include <history/HistoryItem.h>
42 #include <workers/WorkerThread.h>
43 #include <wtf/OwnArrayPtr.h>
44 #include <wtf/text/AtomicString.h>
45
46 unsigned DumpRenderTreeSupportEfl::activeAnimationsCount(const Evas_Object* ewkFrame)
47 {
48     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
49
50     if (!frame)
51         return 0;
52
53     WebCore::AnimationController* animationController = frame->animation();
54
55     if (!animationController)
56         return 0;
57
58     return animationController->numberOfActiveAnimations(frame->document());
59 }
60
61 void DumpRenderTreeSupportEfl::clearFrameName(Evas_Object* ewkFrame)
62 {
63     if (WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame))
64         frame->tree()->clearName();
65 }
66
67 void DumpRenderTreeSupportEfl::clearOpener(Evas_Object* ewkFrame)
68 {
69     if (WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame))
70         frame->loader()->setOpener(0);
71 }
72
73 String DumpRenderTreeSupportEfl::counterValueByElementId(const Evas_Object* ewkFrame, const char* elementId)
74 {
75     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
76
77     if (!frame)
78         return String();
79
80     WebCore::Element* element = frame->document()->getElementById(elementId);
81
82     if (!element)
83         return String();
84
85     return WebCore::counterValueForElement(element);
86 }
87
88 Eina_List* DumpRenderTreeSupportEfl::frameChildren(const Evas_Object* ewkFrame)
89 {
90     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
91
92     if (!frame)
93         return 0;
94
95     Eina_List* childFrames = 0;
96
97     for (unsigned index = 0; index < frame->tree()->childCount(); index++) {
98         WebCore::Frame *childFrame = frame->tree()->child(index);
99         WebCore::FrameLoaderClientEfl *client = static_cast<WebCore::FrameLoaderClientEfl*>(childFrame->loader()->client());
100
101         if (!client)
102             continue;
103
104         childFrames = eina_list_append(childFrames, client->webFrame());
105     }
106
107     return childFrames;
108 }
109
110 WebCore::Frame* DumpRenderTreeSupportEfl::frameParent(const Evas_Object* ewkFrame)
111 {
112     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
113
114     if (!frame)
115         return 0;
116
117     return frame->tree()->parent();
118 }
119
120 void DumpRenderTreeSupportEfl::layoutFrame(Evas_Object* ewkFrame)
121 {
122     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
123
124     if (!frame)
125         return;
126
127     WebCore::FrameView* frameView = frame->view();
128
129     if (!frameView)
130         return;
131
132     frameView->layout();
133 }
134
135 int DumpRenderTreeSupportEfl::numberOfPages(const Evas_Object* ewkFrame, float pageWidth, float pageHeight)
136 {
137     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
138
139     if (!frame)
140         return 0;
141
142     return WebCore::PrintContext::numberOfPages(frame, WebCore::FloatSize(pageWidth, pageHeight));
143 }
144
145 int DumpRenderTreeSupportEfl::numberOfPagesForElementId(const Evas_Object* ewkFrame, const char* elementId, float pageWidth, float pageHeight)
146 {
147     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
148
149     if (!frame)
150         return 0;
151
152     WebCore::Element *element = frame->document()->getElementById(elementId);
153
154     if (!element)
155         return 0;
156
157     return WebCore::PrintContext::pageNumberForElement(element, WebCore::FloatSize(pageWidth, pageHeight));
158 }
159
160 bool DumpRenderTreeSupportEfl::pauseAnimation(Evas_Object* ewkFrame, const char* name, const char* elementId, double time)
161 {
162     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
163
164     if (!frame)
165         return false;
166
167     WebCore::Element* element = frame->document()->getElementById(elementId);
168
169     if (!element || !element->renderer())
170         return false;
171
172     return frame->animation()->pauseAnimationAtTime(element->renderer(), name, time);
173 }
174
175 bool DumpRenderTreeSupportEfl::pauseTransition(Evas_Object* ewkFrame, const char* name, const char* elementId, double time)
176 {
177     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
178
179     if (!frame)
180         return false;
181
182     WebCore::Element* element = frame->document()->getElementById(elementId);
183
184     if (!element || !element->renderer())
185         return false;
186
187     return frame->animation()->pauseTransitionAtTime(element->renderer(), name, time);
188 }
189
190 unsigned DumpRenderTreeSupportEfl::pendingUnloadEventCount(const Evas_Object* ewkFrame)
191 {
192     if (WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame))
193         return frame->domWindow()->pendingUnloadEventListeners();
194
195     return 0;
196 }
197
198 String DumpRenderTreeSupportEfl::renderTreeDump(Evas_Object* ewkFrame)
199 {
200     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
201
202     if (!frame)
203         return String();
204
205     WebCore::FrameView *frameView = frame->view();
206
207     if (frameView && frameView->layoutPending())
208         frameView->layout();
209
210     return WebCore::externalRepresentation(frame);
211 }
212
213 String DumpRenderTreeSupportEfl::responseMimeType(const Evas_Object* ewkFrame)
214 {
215     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
216
217     if (!frame)
218         return String();
219
220     WebCore::DocumentLoader *documentLoader = frame->loader()->documentLoader();
221
222     if (!documentLoader)
223         return String();
224
225     return documentLoader->responseMIMEType();
226 }
227
228 void DumpRenderTreeSupportEfl::resumeAnimations(Evas_Object* ewkFrame)
229 {
230     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
231
232     if (!frame)
233         return;
234
235     WebCore::AnimationController *animationController = frame->animation();
236     if (animationController)
237         animationController->resumeAnimations();
238 }
239
240 WebCore::IntRect DumpRenderTreeSupportEfl::selectionRectangle(const Evas_Object* ewkFrame)
241 {
242     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
243
244     if (!frame)
245         return WebCore::IntRect();
246
247     return enclosingIntRect(frame->selection()->bounds());
248 }
249
250 // Compare with "WebKit/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm
251 String DumpRenderTreeSupportEfl::suitableDRTFrameName(const Evas_Object* ewkFrame)
252 {
253     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
254
255     if (!frame)
256         return String();
257
258     const String frameName(ewk_frame_name_get(ewkFrame));
259
260     if (ewkFrame == ewk_view_frame_main_get(ewk_frame_view_get(ewkFrame))) {
261         if (!frameName.isEmpty())
262             return String("main frame \"") + frameName + String("\"");
263
264         return String("main frame");
265     }
266
267     if (!frameName.isEmpty())
268         return String("frame \"") + frameName + String("\"");
269
270     return String("frame (anonymous)");
271 }
272
273 void DumpRenderTreeSupportEfl::suspendAnimations(Evas_Object* ewkFrame)
274 {
275     WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame);
276
277     if (!frame)
278         return;
279
280     WebCore::AnimationController *animationController = frame->animation();
281     if (animationController)
282         animationController->suspendAnimations();
283 }
284
285 void DumpRenderTreeSupportEfl::setValueForUser(JSContextRef context, JSValueRef nodeObject, JSStringRef value)
286 {
287     JSC::ExecState* exec = toJS(context);
288     WebCore::Element* element = WebCore::toElement(toJS(exec, nodeObject));
289     if (!element)
290         return;
291     WebCore::HTMLInputElement* inputElement = element->toInputElement();
292     if (!inputElement)
293         return;
294
295     size_t bufferSize = JSStringGetMaximumUTF8CStringSize(value);
296     OwnArrayPtr<char> valueBuffer = adoptArrayPtr(new char[bufferSize]);
297     JSStringGetUTF8CString(value, valueBuffer.get(), bufferSize);
298     inputElement->setValueForUser(String::fromUTF8(valueBuffer.get()));
299 }
300
301 void DumpRenderTreeSupportEfl::setAutofilled(JSContextRef context, JSValueRef nodeObject, bool autofilled)
302 {
303     JSC::ExecState* exec = toJS(context);
304     WebCore::Element* element = WebCore::toElement(toJS(exec, nodeObject));
305     if (!element)
306         return;
307     WebCore::HTMLInputElement* inputElement = element->toInputElement();
308     if (!inputElement)
309         return;
310
311     inputElement->setAutofilled(autofilled);
312 }
313
314 bool DumpRenderTreeSupportEfl::findString(const Evas_Object* ewkView, const char* text, WebCore::FindOptions options)
315 {
316     WebCore::Page* page = EWKPrivate::corePage(ewkView);
317
318     if (!page)
319         return false;
320
321     return page->findString(String::fromUTF8(text), options);
322 }
323
324 void DumpRenderTreeSupportEfl::garbageCollectorCollect()
325 {
326     WebCore::gcController().garbageCollectNow();
327 }
328
329 void DumpRenderTreeSupportEfl::garbageCollectorCollectOnAlternateThread(bool waitUntilDone)
330 {
331     WebCore::gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone);
332 }
333
334 size_t DumpRenderTreeSupportEfl::javaScriptObjectsCount()
335 {
336     return WebCore::JSDOMWindow::commonJSGlobalData()->heap.objectCount();
337 }
338
339 unsigned DumpRenderTreeSupportEfl::workerThreadCount()
340 {
341 #if ENABLE(WORKERS)
342     return WebCore::WorkerThread::workerThreadCount();
343 #else
344     return 0;
345 #endif
346 }
347
348 HistoryItemChildrenVector DumpRenderTreeSupportEfl::childHistoryItems(const Ewk_History_Item* ewkHistoryItem)
349 {
350     WebCore::HistoryItem* historyItem = EWKPrivate::coreHistoryItem(ewkHistoryItem);
351     HistoryItemChildrenVector kids;
352
353     if (!historyItem)
354         return kids;
355
356     const WebCore::HistoryItemVector& children = historyItem->children();
357     const unsigned size = children.size();
358
359     for (unsigned i = 0; i < size; ++i) {
360         Ewk_History_Item* kid = ewk_history_item_new_from_core(children[i].get());
361         kids.append(kid);
362     }
363
364     return kids;
365 }
366
367 String DumpRenderTreeSupportEfl::historyItemTarget(const Ewk_History_Item* ewkHistoryItem)
368 {
369     WebCore::HistoryItem* historyItem = EWKPrivate::coreHistoryItem(ewkHistoryItem);
370
371     if (!historyItem)
372         return String();
373
374     return historyItem->target();
375 }
376
377 bool DumpRenderTreeSupportEfl::isTargetItem(const Ewk_History_Item* ewkHistoryItem)
378 {
379     WebCore::HistoryItem* historyItem = EWKPrivate::coreHistoryItem(ewkHistoryItem);
380
381     if (!historyItem)
382         return false;
383
384     return historyItem->isTargetItem();
385 }
386
387 void DumpRenderTreeSupportEfl::setMockScrollbarsEnabled(bool enable)
388 {
389     WebCore::Settings::setMockScrollbarsEnabled(enable);
390 }
391
392 void DumpRenderTreeSupportEfl::dumpConfigurationForViewport(Evas_Object* ewkView, int deviceDPI, const WebCore::IntSize& deviceSize, const WebCore::IntSize& availableSize)
393 {
394     WebCore::Page* page = EWKPrivate::corePage(ewkView);
395
396     if (!page)
397         return;
398     WebCore::ViewportArguments arguments = page->mainFrame()->document()->viewportArguments();
399     WebCore::ViewportAttributes attributes = computeViewportAttributes(arguments,
400             /* default layout width for non-mobile pages */ 980,
401             deviceSize.width(), deviceSize.height(),
402             deviceDPI,
403             availableSize);
404     restrictMinimumScaleFactorToViewportSize(attributes, availableSize);
405     restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);
406     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);
407 }