ba712d113d840b5205e48a568517653e8b7acd97
[WebKit-https.git] / Source / WebKit / qt / WebCoreSupport / DumpRenderTreeSupportQt.cpp
1 /*
2     Copyright (C) 2010 Robert Hogan <robert@roberthogan.net>
3     Copyright (C) 2008,2009,2010 Nokia Corporation and/or its subsidiary(-ies)
4     Copyright (C) 2007 Staikos Computing Services Inc.
5     Copyright (C) 2007 Apple Inc.
6
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Library 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     Library General Public License for more details.
16
17     You should have received a copy of the GNU Library General Public License
18     along with this library; see the file COPYING.LIB.  If not, write to
19     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20     Boston, MA 02110-1301, USA.
21 */
22
23 #include "config.h"
24 #include "DumpRenderTreeSupportQt.h"
25
26 #include "ApplicationCacheStorage.h"
27 #include "CSSComputedStyleDeclaration.h"
28 #include "ChromeClientQt.h"
29 #include "ContextMenu.h"
30 #include "ContextMenuClientQt.h"
31 #include "ContextMenuController.h"
32 #include "DeviceOrientation.h"
33 #include "DeviceOrientationClientMockQt.h"
34 #include "DocumentLoader.h"
35 #include "Editor.h"
36 #include "EditorClientQt.h"
37 #include "Element.h"
38 #include "FocusController.h"
39 #include "Frame.h"
40 #include "FrameLoaderClientQt.h"
41 #include "FrameView.h"
42 #if USE(JSC)
43 #include "GCController.h"
44 #elif USE(V8)
45 #include "V8GCController.h"
46 #include "V8Proxy.h"
47 #endif
48 #include "GeolocationClient.h"
49 #include "GeolocationClientMock.h"
50 #include "GeolocationController.h"
51 #include "GeolocationError.h"
52 #include "GeolocationPosition.h"
53 #include "HistoryItem.h"
54 #include "HTMLInputElement.h"
55 #include "InspectorController.h"
56 #include "NodeList.h"
57 #include "NotificationPresenterClientQt.h"
58 #include "Page.h"
59 #include "PageGroup.h"
60 #include "PluginDatabase.h"
61 #include "PositionError.h"
62 #include "PrintContext.h"
63 #include "RenderListItem.h"
64 #include "RenderTreeAsText.h"
65 #include "ScriptController.h"
66 #include "SecurityOrigin.h"
67 #include "Settings.h"
68 #if ENABLE(SVG)
69 #include "SVGDocumentExtensions.h"
70 #include "SVGSMILElement.h"
71 #endif
72 #include "TextIterator.h"
73 #include "WorkerThread.h"
74 #include <wtf/CurrentTime.h>
75
76 #include "qwebelement.h"
77 #include "qwebframe.h"
78 #include "qwebframe_p.h"
79 #include "qwebhistory.h"
80 #include "qwebhistory_p.h"
81 #include "qwebpage.h"
82 #include "qwebpage_p.h"
83 #include "qwebscriptworld.h"
84
85 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
86 #include "HTMLVideoElement.h"
87 #include "MediaPlayerPrivateQt.h"
88 #endif
89
90 using namespace WebCore;
91
92 QMap<int, QWebScriptWorld*> m_worldMap;
93
94 #if ENABLE(CLIENT_BASED_GEOLOCATION)
95 GeolocationClientMock* toGeolocationClientMock(GeolocationClient* client)
96 {
97      ASSERT(QWebPagePrivate::drtRun);
98      return static_cast<GeolocationClientMock*>(client);
99 }
100 #endif
101
102 QDRTNode::QDRTNode()
103     : m_node(0)
104 {
105 }
106
107 QDRTNode::QDRTNode(WebCore::Node* node)
108     : m_node(0)
109 {
110     if (node) {
111         m_node = node;
112         m_node->ref();
113     }
114 }
115
116 QDRTNode::~QDRTNode()
117 {
118     if (m_node)
119         m_node->deref();
120 }
121
122 QDRTNode::QDRTNode(const QDRTNode& other)
123     :m_node(other.m_node)
124 {
125     if (m_node)
126         m_node->ref();
127 }
128
129 QDRTNode& QDRTNode::operator=(const QDRTNode& other)
130 {
131     if (this != &other) {
132         Node* otherNode = other.m_node;
133         if (otherNode)
134             otherNode->ref();
135         if (m_node)
136             m_node->deref();
137         m_node = otherNode;
138     }
139     return *this;
140 }
141
142
143 DumpRenderTreeSupportQt::DumpRenderTreeSupportQt()
144 {
145 }
146
147 DumpRenderTreeSupportQt::~DumpRenderTreeSupportQt()
148 {
149 }
150
151 void DumpRenderTreeSupportQt::overwritePluginDirectories()
152 {
153     PluginDatabase* db = PluginDatabase::installedPlugins(/* populate */ false);
154
155     Vector<String> paths;
156     String qtPath(qgetenv("QTWEBKIT_PLUGIN_PATH").data());
157     qtPath.split(UChar(':'), /* allowEmptyEntries */ false, paths);
158
159     db->setPluginDirectories(paths);
160     db->refresh();
161 }
162
163 int DumpRenderTreeSupportQt::workerThreadCount()
164 {
165 #if ENABLE(WORKERS)
166     return WebCore::WorkerThread::workerThreadCount();
167 #else
168     return 0;
169 #endif
170 }
171
172 void DumpRenderTreeSupportQt::setDumpRenderTreeModeEnabled(bool b)
173 {
174     QWebPagePrivate::drtRun = b;
175 }
176
177 void DumpRenderTreeSupportQt::setFrameFlatteningEnabled(QWebPage* page, bool enabled)
178 {
179     QWebPagePrivate::core(page)->settings()->setFrameFlatteningEnabled(enabled);
180 }
181
182 void DumpRenderTreeSupportQt::webPageSetGroupName(QWebPage* page, const QString& groupName)
183 {
184     page->handle()->page->setGroupName(groupName);
185 }
186
187 QString DumpRenderTreeSupportQt::webPageGroupName(QWebPage* page)
188 {
189     return page->handle()->page->groupName();
190 }
191
192 void DumpRenderTreeSupportQt::webInspectorExecuteScript(QWebPage* page, long callId, const QString& script)
193 {
194 #if ENABLE(INSPECTOR)
195     if (!page->handle()->page->inspectorController())
196         return;
197     page->handle()->page->inspectorController()->evaluateForTestInFrontend(callId, script);
198 #endif
199 }
200
201 void DumpRenderTreeSupportQt::webInspectorClose(QWebPage* page)
202 {
203 #if ENABLE(INSPECTOR)
204     if (!page->handle()->page->inspectorController())
205         return;
206     page->handle()->page->inspectorController()->close();
207 #endif
208 }
209
210 void DumpRenderTreeSupportQt::webInspectorShow(QWebPage* page)
211 {
212 #if ENABLE(INSPECTOR)
213     if (!page->handle()->page->inspectorController())
214         return;
215     page->handle()->page->inspectorController()->show();
216 #endif
217 }
218
219 void DumpRenderTreeSupportQt::setTimelineProfilingEnabled(QWebPage* page, bool enabled)
220 {
221 #if ENABLE(INSPECTOR)
222     InspectorController* controller = page->handle()->page->inspectorController();
223     if (!controller)
224         return;
225     if (enabled)
226         controller->startTimelineProfiler();
227     else
228         controller->stopTimelineProfiler();
229 #endif
230 }
231
232 bool DumpRenderTreeSupportQt::hasDocumentElement(QWebFrame* frame)
233 {
234     return QWebFramePrivate::core(frame)->document()->documentElement();
235 }
236
237 void DumpRenderTreeSupportQt::setJavaScriptProfilingEnabled(QWebFrame* frame, bool enabled)
238 {
239 #if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
240     Frame* coreFrame = QWebFramePrivate::core(frame);
241     InspectorController* controller = coreFrame->page()->inspectorController();
242     if (!controller)
243         return;
244     if (enabled)
245         controller->enableProfiler();
246     else
247         controller->disableProfiler();
248 #endif
249 }
250
251 // Pause a given CSS animation or transition on the target node at a specific time.
252 // If the animation or transition is already paused, it will update its pause time.
253 // This method is only intended to be used for testing the CSS animation and transition system.
254 bool DumpRenderTreeSupportQt::pauseAnimation(QWebFrame *frame, const QString &animationName, double time, const QString &elementId)
255 {
256     Frame* coreFrame = QWebFramePrivate::core(frame);
257     if (!coreFrame)
258         return false;
259
260     AnimationController* controller = coreFrame->animation();
261     if (!controller)
262         return false;
263
264     Document* doc = coreFrame->document();
265     Q_ASSERT(doc);
266
267     Node* coreNode = doc->getElementById(elementId);
268     if (!coreNode || !coreNode->renderer())
269         return false;
270
271     return controller->pauseAnimationAtTime(coreNode->renderer(), animationName, time);
272 }
273
274 bool DumpRenderTreeSupportQt::pauseTransitionOfProperty(QWebFrame *frame, const QString &propertyName, double time, const QString &elementId)
275 {
276     Frame* coreFrame = QWebFramePrivate::core(frame);
277     if (!coreFrame)
278         return false;
279
280     AnimationController* controller = coreFrame->animation();
281     if (!controller)
282         return false;
283
284     Document* doc = coreFrame->document();
285     Q_ASSERT(doc);
286
287     Node* coreNode = doc->getElementById(elementId);
288     if (!coreNode || !coreNode->renderer())
289         return false;
290
291     return controller->pauseTransitionAtTime(coreNode->renderer(), propertyName, time);
292 }
293
294 // Pause a given SVG animation on the target node at a specific time.
295 // This method is only intended to be used for testing the SVG animation system.
296 bool DumpRenderTreeSupportQt::pauseSVGAnimation(QWebFrame *frame, const QString &animationId, double time, const QString &elementId)
297 {
298 #if !ENABLE(SVG)
299     return false;
300 #else
301     Frame* coreFrame = QWebFramePrivate::core(frame);
302     if (!coreFrame)
303         return false;
304
305     Document* doc = coreFrame->document();
306     Q_ASSERT(doc);
307
308     if (!doc->svgExtensions())
309         return false;
310
311     Node* coreNode = doc->getElementById(animationId);
312     if (!coreNode || !SVGSMILElement::isSMILElement(coreNode))
313         return false;
314
315     return doc->accessSVGExtensions()->sampleAnimationAtTime(elementId, static_cast<SVGSMILElement*>(coreNode), time);
316 #endif
317 }
318
319 // Returns the total number of currently running animations (includes both CSS transitions and CSS animations).
320 int DumpRenderTreeSupportQt::numberOfActiveAnimations(QWebFrame *frame)
321 {
322     Frame* coreFrame = QWebFramePrivate::core(frame);
323     if (!coreFrame)
324         return false;
325
326     AnimationController* controller = coreFrame->animation();
327     if (!controller)
328         return false;
329
330     return controller->numberOfActiveAnimations();
331 }
332
333 void DumpRenderTreeSupportQt::suspendAnimations(QWebFrame *frame)
334 {
335     Frame* coreFrame = QWebFramePrivate::core(frame);
336     if (!coreFrame)
337         return;
338
339     AnimationController* controller = coreFrame->animation();
340     if (!controller)
341         return;
342
343     controller->suspendAnimations();
344 }
345
346 void DumpRenderTreeSupportQt::resumeAnimations(QWebFrame *frame)
347 {
348     Frame* coreFrame = QWebFramePrivate::core(frame);
349     if (!coreFrame)
350         return;
351
352     AnimationController* controller = coreFrame->animation();
353     if (!controller)
354         return;
355
356     controller->resumeAnimations();
357 }
358
359 void DumpRenderTreeSupportQt::clearFrameName(QWebFrame* frame)
360 {
361     Frame* coreFrame = QWebFramePrivate::core(frame);
362     coreFrame->tree()->clearName();
363 }
364
365 int DumpRenderTreeSupportQt::javaScriptObjectsCount()
366 {
367 #if USE(JSC)
368     return JSDOMWindowBase::commonJSGlobalData()->heap.globalObjectCount();
369 #elif USE(V8)
370     // FIXME: Find a way to do this using V8.
371     return 1;
372 #endif
373 }
374
375 void DumpRenderTreeSupportQt::garbageCollectorCollect()
376 {
377 #if USE(JSC)
378     gcController().garbageCollectNow();
379 #elif USE(V8)
380     v8::V8::LowMemoryNotification();
381 #endif
382 }
383
384 void DumpRenderTreeSupportQt::garbageCollectorCollectOnAlternateThread(bool waitUntilDone)
385 {
386 #if USE(JSC)
387     gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone);
388 #elif USE(V8)
389     // FIXME: Find a way to do this using V8.
390     garbageCollectorCollect();
391 #endif
392 }
393
394 // Returns the value of counter in the element specified by \a id.
395 QString DumpRenderTreeSupportQt::counterValueForElementById(QWebFrame* frame, const QString& id)
396 {
397     Frame* coreFrame = QWebFramePrivate::core(frame);
398     if (Document* document = coreFrame->document()) {
399         if (Element* element = document->getElementById(id))
400             return WebCore::counterValueForElement(element);
401     }
402     return QString();
403 }
404
405 int DumpRenderTreeSupportQt::pageNumberForElementById(QWebFrame* frame, const QString& id, float width, float height)
406 {
407     Frame* coreFrame = QWebFramePrivate::core(frame);
408     if (!coreFrame)
409         return -1;
410
411     Element* element = coreFrame->document()->getElementById(AtomicString(id));
412     if (!element)
413         return -1;
414
415     return PrintContext::pageNumberForElement(element, FloatSize(width, height));
416 }
417
418 int DumpRenderTreeSupportQt::numberOfPages(QWebFrame* frame, float width, float height)
419 {
420     Frame* coreFrame = QWebFramePrivate::core(frame);
421     if (!coreFrame)
422         return -1;
423
424     return PrintContext::numberOfPages(coreFrame, FloatSize(width, height));
425 }
426
427 // Suspend active DOM objects in this frame.
428 void DumpRenderTreeSupportQt::suspendActiveDOMObjects(QWebFrame* frame)
429 {
430     Frame* coreFrame = QWebFramePrivate::core(frame);
431     if (coreFrame->document())
432         // FIXME: This function should be changed take a ReasonForSuspension parameter 
433         // https://bugs.webkit.org/show_bug.cgi?id=45732
434         coreFrame->document()->suspendActiveDOMObjects(ActiveDOMObject::JavaScriptDebuggerPaused);
435 }
436
437 // Resume active DOM objects in this frame.
438 void DumpRenderTreeSupportQt::resumeActiveDOMObjects(QWebFrame* frame)
439 {
440     Frame* coreFrame = QWebFramePrivate::core(frame);
441     if (coreFrame->document())
442         coreFrame->document()->resumeActiveDOMObjects();
443 }
444
445 void DumpRenderTreeSupportQt::whiteListAccessFromOrigin(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains)
446 {
447     SecurityOrigin::addOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains);
448 }
449
450 void DumpRenderTreeSupportQt::removeWhiteListAccessFromOrigin(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains)
451 {
452     SecurityOrigin::removeOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains);
453 }
454
455 void DumpRenderTreeSupportQt::resetOriginAccessWhiteLists()
456 {
457     SecurityOrigin::resetOriginAccessWhitelists();
458 }
459
460 void DumpRenderTreeSupportQt::setDomainRelaxationForbiddenForURLScheme(bool forbidden, const QString& scheme)
461 {
462     SecurityOrigin::setDomainRelaxationForbiddenForURLScheme(forbidden, scheme);
463 }
464
465 void DumpRenderTreeSupportQt::setCaretBrowsingEnabled(QWebPage* page, bool value)
466 {
467     page->handle()->page->settings()->setCaretBrowsingEnabled(value);
468 }
469
470 void DumpRenderTreeSupportQt::setMediaType(QWebFrame* frame, const QString& type)
471 {
472     WebCore::Frame* coreFrame = QWebFramePrivate::core(frame);
473     WebCore::FrameView* view = coreFrame->view();
474     view->setMediaType(type);
475     coreFrame->document()->styleSelectorChanged(RecalcStyleImmediately);
476     view->layout();
477 }
478
479 void DumpRenderTreeSupportQt::setSmartInsertDeleteEnabled(QWebPage* page, bool enabled)
480 {
481     page->d->smartInsertDeleteEnabled = enabled;
482 }
483
484
485 void DumpRenderTreeSupportQt::setSelectTrailingWhitespaceEnabled(QWebPage* page, bool enabled)
486 {
487     page->d->selectTrailingWhitespaceEnabled = enabled;
488 }
489
490
491 void DumpRenderTreeSupportQt::executeCoreCommandByName(QWebPage* page, const QString& name, const QString& value)
492 {
493     page->handle()->page->focusController()->focusedOrMainFrame()->editor()->command(name).execute(value);
494 }
495
496 bool DumpRenderTreeSupportQt::isCommandEnabled(QWebPage* page, const QString& name)
497 {
498     return page->handle()->page->focusController()->focusedOrMainFrame()->editor()->command(name).isEnabled();
499 }
500
501 bool DumpRenderTreeSupportQt::findString(QWebPage* page, const QString& string, const QStringList& optionArray)
502 {
503     // 1. Parse the options from the array
504     WebCore::FindOptions options = 0;
505     const int optionCount = optionArray.size();
506     for (int i = 0; i < optionCount; ++i) {
507         const QString& option = optionArray.at(i);
508         if (option == QLatin1String("CaseInsensitive"))
509             options |= WebCore::CaseInsensitive;
510         else if (option == QLatin1String("AtWordStarts"))
511             options |= WebCore::AtWordStarts;
512         else if (option == QLatin1String("TreatMedialCapitalAsWordStart"))
513             options |= WebCore::TreatMedialCapitalAsWordStart;
514         else if (option == QLatin1String("Backwards"))
515             options |= WebCore::Backwards;
516         else if (option == QLatin1String("WrapAround"))
517             options |= WebCore::WrapAround;
518         else if (option == QLatin1String("StartInSelection"))
519             options |= WebCore::StartInSelection;
520     }
521
522     // 2. find the string
523     WebCore::Frame* frame = page->handle()->page->focusController()->focusedOrMainFrame();
524     return frame && frame->editor()->findString(string, options);
525 }
526
527 QString DumpRenderTreeSupportQt::markerTextForListItem(const QWebElement& listItem)
528 {
529     return WebCore::markerTextForListItem(listItem.m_element);
530 }
531
532 static QString convertToPropertyName(const QString& name)
533 {
534     QStringList parts = name.split(QLatin1Char('-'));
535     QString camelCaseName;
536     for (int j = 0; j < parts.count(); ++j) {
537         QString part = parts.at(j);
538         if (j)
539             camelCaseName.append(part.replace(0, 1, part.left(1).toUpper()));
540         else
541             camelCaseName.append(part);
542     }
543     return camelCaseName;
544 }
545
546 QVariantMap DumpRenderTreeSupportQt::computedStyleIncludingVisitedInfo(const QWebElement& element)
547 {
548     QVariantMap res;
549
550     WebCore::Element* webElement = element.m_element;
551     if (!webElement)
552         return res;
553
554     RefPtr<WebCore::CSSComputedStyleDeclaration> style = computedStyle(webElement, true);
555     for (int i = 0; i < style->length(); i++) {
556         QString name = style->item(i);
557         QString value = (static_cast<WebCore::CSSStyleDeclaration*>(style.get()))->getPropertyValue(name);
558         res[convertToPropertyName(name)] = QVariant(value);
559     }
560     return res;
561 }
562
563 QVariantList DumpRenderTreeSupportQt::selectedRange(QWebPage* page)
564 {
565     WebCore::Frame* frame = page->handle()->page->focusController()->focusedOrMainFrame();
566     QVariantList selectedRange;
567     RefPtr<Range> range = frame->selection()->toNormalizedRange().get();
568
569     Element* selectionRoot = frame->selection()->rootEditableElement();
570     Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement();
571
572     RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset());
573     ASSERT(testRange->startContainer() == scope);
574     int startPosition = TextIterator::rangeLength(testRange.get());
575
576     ExceptionCode ec;
577     testRange->setEnd(range->endContainer(), range->endOffset(), ec);
578     ASSERT(testRange->startContainer() == scope);
579     int endPosition = TextIterator::rangeLength(testRange.get());
580
581     selectedRange << startPosition << (endPosition - startPosition);
582
583     return selectedRange;
584
585 }
586
587 QVariantList DumpRenderTreeSupportQt::firstRectForCharacterRange(QWebPage* page, int location, int length)
588 {
589     WebCore::Frame* frame = page->handle()->page->focusController()->focusedOrMainFrame();
590     QVariantList rect;
591
592     if ((location + length < location) && (location + length))
593         length = 0;
594
595     Element* selectionRoot = frame->selection()->rootEditableElement();
596     Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement();
597     RefPtr<Range> range = TextIterator::rangeFromLocationAndLength(scope, location, length);
598
599     if (!range)
600         return QVariantList();
601
602     QRect resultRect = frame->editor()->firstRectForRange(range.get());
603     rect << resultRect.x() << resultRect.y() << resultRect.width() << resultRect.height();
604     return rect;
605 }
606
607 bool DumpRenderTreeSupportQt::elementDoesAutoCompleteForElementWithId(QWebFrame* frame, const QString& elementId)
608 {
609     Frame* coreFrame = QWebFramePrivate::core(frame);
610     if (!coreFrame)
611         return false;
612
613     Document* doc = coreFrame->document();
614     Q_ASSERT(doc);
615
616     Node* coreNode = doc->getElementById(elementId);
617     if (!coreNode || !coreNode->renderer())
618         return false;
619
620     HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(coreNode);
621
622     return inputElement->isTextField() && !inputElement->isPasswordField() && inputElement->autoComplete();
623 }
624
625 void DumpRenderTreeSupportQt::setEditingBehavior(QWebPage* page, const QString& editingBehavior)
626 {
627     WebCore::EditingBehaviorType coreEditingBehavior;
628
629     if (editingBehavior == QLatin1String("win"))
630         coreEditingBehavior = EditingWindowsBehavior;
631     else if (editingBehavior == QLatin1String("mac"))
632         coreEditingBehavior = EditingMacBehavior;
633     else if (editingBehavior == QLatin1String("unix"))
634         coreEditingBehavior = EditingUnixBehavior;
635     else {
636         ASSERT_NOT_REACHED();
637         return;
638     }
639
640     Page* corePage = QWebPagePrivate::core(page);
641     if (!corePage)
642         return;
643
644     corePage->settings()->setEditingBehaviorType(coreEditingBehavior);
645 }
646
647 void DumpRenderTreeSupportQt::clearAllApplicationCaches()
648 {
649 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
650     WebCore::cacheStorage().empty();
651     WebCore::cacheStorage().vacuumDatabaseFile();
652 #endif
653 }
654
655 void DumpRenderTreeSupportQt::dumpFrameLoader(bool b)
656 {
657     FrameLoaderClientQt::dumpFrameLoaderCallbacks = b;
658 }
659
660 void DumpRenderTreeSupportQt::dumpUserGestureInFrameLoader(bool b)
661 {
662     FrameLoaderClientQt::dumpUserGestureInFrameLoaderCallbacks = b;
663 }
664
665 void DumpRenderTreeSupportQt::dumpResourceLoadCallbacks(bool b)
666 {
667     FrameLoaderClientQt::dumpResourceLoadCallbacks = b;
668 }
669
670 void DumpRenderTreeSupportQt::dumpResourceLoadCallbacksPath(const QString& path)
671 {
672     FrameLoaderClientQt::dumpResourceLoadCallbacksPath = path;
673 }
674
675 void DumpRenderTreeSupportQt::dumpResourceResponseMIMETypes(bool b)
676 {
677     FrameLoaderClientQt::dumpResourceResponseMIMETypes = b;
678 }
679
680 void DumpRenderTreeSupportQt::setWillSendRequestReturnsNullOnRedirect(bool b)
681 {
682     FrameLoaderClientQt::sendRequestReturnsNullOnRedirect = b;
683 }
684
685 void DumpRenderTreeSupportQt::setWillSendRequestReturnsNull(bool b)
686 {
687     FrameLoaderClientQt::sendRequestReturnsNull = b;
688 }
689
690 void DumpRenderTreeSupportQt::setWillSendRequestClearHeaders(const QStringList& headers)
691 {
692     FrameLoaderClientQt::sendRequestClearHeaders = headers;
693 }
694
695 void DumpRenderTreeSupportQt::setDeferMainResourceDataLoad(bool b)
696 {
697     FrameLoaderClientQt::deferMainResourceDataLoad = b;
698 }
699
700 void DumpRenderTreeSupportQt::setCustomPolicyDelegate(bool enabled, bool permissive)
701 {
702     FrameLoaderClientQt::policyDelegateEnabled = enabled;
703     FrameLoaderClientQt::policyDelegatePermissive = permissive;
704 }
705
706 void DumpRenderTreeSupportQt::dumpHistoryCallbacks(bool b)
707 {
708     FrameLoaderClientQt::dumpHistoryCallbacks = b;
709 }
710
711 void DumpRenderTreeSupportQt::dumpVisitedLinksCallbacks(bool b)
712 {
713     ChromeClientQt::dumpVisitedLinksCallbacks = b;
714 }
715
716 void DumpRenderTreeSupportQt::dumpEditingCallbacks(bool b)
717 {
718     EditorClientQt::dumpEditingCallbacks = b;
719 }
720
721 void DumpRenderTreeSupportQt::dumpSetAcceptsEditing(bool b)
722 {
723     EditorClientQt::acceptsEditing = b;
724 }
725
726 void DumpRenderTreeSupportQt::dumpNotification(bool b)
727 {
728 #if ENABLE(NOTIFICATIONS)
729     NotificationPresenterClientQt::dumpNotification = b;
730 #endif
731 }
732
733 QString DumpRenderTreeSupportQt::viewportAsText(QWebPage* page, int deviceDPI, const QSize& deviceSize, const QSize& availableSize)
734 {
735     WebCore::ViewportArguments args = page->d->viewportArguments();
736
737     WebCore::ViewportAttributes conf = WebCore::computeViewportAttributes(args,
738         /* desktop-width */ 980,
739         /* device-width  */ deviceSize.width(),
740         /* device-height */ deviceSize.height(),
741         /* device-dpi    */ deviceDPI,
742         availableSize);
743
744     QString res;
745     res = res.sprintf("viewport size %dx%d scale %f with limits [%f, %f] and userScalable %f\n",
746             conf.layoutSize.width(),
747             conf.layoutSize.height(),
748             conf.initialScale,
749             conf.minimumScale,
750             conf.maximumScale,
751             conf.userScalable);
752
753     return res;
754 }
755
756 void DumpRenderTreeSupportQt::activeMockDeviceOrientationClient(bool b)
757 {
758 #if ENABLE(DEVICE_ORIENTATION)
759     DeviceOrientationClientMockQt::mockIsActive = b;
760 #endif
761 }
762
763 void DumpRenderTreeSupportQt::removeMockDeviceOrientation()
764 {
765 #if ENABLE(DEVICE_ORIENTATION)
766     DeviceOrientationClientMockQt* client = DeviceOrientationClientMockQt::client();
767     delete client;
768 #endif
769 }
770
771 void DumpRenderTreeSupportQt::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma)
772 {
773 #if ENABLE(DEVICE_ORIENTATION)
774     DeviceOrientationClientMockQt::client()->setOrientation(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma);
775 #endif
776 }
777
778 void DumpRenderTreeSupportQt::resetGeolocationMock(QWebPage* page)
779 {
780 #if ENABLE(CLIENT_BASED_GEOLOCATION)
781     Page* corePage = QWebPagePrivate::core(page);
782     GeolocationClientMock* mockClient = toGeolocationClientMock(corePage->geolocationController()->client());
783     mockClient->reset();
784 #endif
785 }
786
787 void DumpRenderTreeSupportQt::setMockGeolocationPermission(QWebPage* page, bool allowed)
788 {
789 #if ENABLE(CLIENT_BASED_GEOLOCATION)
790     Page* corePage = QWebPagePrivate::core(page);
791     GeolocationClientMock* mockClient = toGeolocationClientMock(corePage->geolocationController()->client());
792     mockClient->setPermission(allowed);
793 #endif
794 }
795
796 void DumpRenderTreeSupportQt::setMockGeolocationPosition(QWebPage* page, double latitude, double longitude, double accuracy)
797 {
798 #if ENABLE(CLIENT_BASED_GEOLOCATION)
799     Page* corePage = QWebPagePrivate::core(page);
800     GeolocationClientMock* mockClient = toGeolocationClientMock(corePage->geolocationController()->client());
801     mockClient->setPosition(GeolocationPosition::create(currentTime(), latitude, longitude, accuracy));
802 #endif
803 }
804
805 void DumpRenderTreeSupportQt::setMockGeolocationError(QWebPage* page, int errorCode, const QString& message)
806 {
807 #if ENABLE(CLIENT_BASED_GEOLOCATION)
808     Page* corePage = QWebPagePrivate::core(page);
809
810     GeolocationError::ErrorCode code = GeolocationError::PositionUnavailable;
811     switch (errorCode) {
812     case PositionError::PERMISSION_DENIED:
813         code = GeolocationError::PermissionDenied;
814         break;
815     case PositionError::POSITION_UNAVAILABLE:
816         code = GeolocationError::PositionUnavailable;
817         break;
818     }
819
820     GeolocationClientMock* mockClient = static_cast<GeolocationClientMock*>(corePage->geolocationController()->client());
821     mockClient->setError(GeolocationError::create(code, message));
822 #endif
823 }
824
825 bool DumpRenderTreeSupportQt::isTargetItem(const QWebHistoryItem& historyItem)
826 {
827     QWebHistoryItem it = historyItem;
828     if (QWebHistoryItemPrivate::core(&it)->isTargetItem())
829         return true;
830     return false;
831 }
832
833 QString DumpRenderTreeSupportQt::historyItemTarget(const QWebHistoryItem& historyItem)
834 {
835     QWebHistoryItem it = historyItem;
836     return (QWebHistoryItemPrivate::core(&it)->target());
837 }
838
839 QMap<QString, QWebHistoryItem> DumpRenderTreeSupportQt::getChildHistoryItems(const QWebHistoryItem& historyItem)
840 {
841     QWebHistoryItem it = historyItem;
842     HistoryItem* item = QWebHistoryItemPrivate::core(&it);
843     const WebCore::HistoryItemVector& children = item->children();
844
845     unsigned size = children.size();
846     QMap<QString, QWebHistoryItem> kids;
847     for (unsigned i = 0; i < size; ++i) {
848         QWebHistoryItem kid(new QWebHistoryItemPrivate(children[i].get()));
849         kids.insert(DumpRenderTreeSupportQt::historyItemTarget(kid), kid);
850     }
851     return kids;
852 }
853
854 bool DumpRenderTreeSupportQt::shouldClose(QWebFrame* frame)
855 {
856     WebCore::Frame* coreFrame = QWebFramePrivate::core(frame);
857     return coreFrame->loader()->shouldClose();
858 }
859
860 void DumpRenderTreeSupportQt::clearScriptWorlds()
861 {
862     m_worldMap.clear();
863 }
864
865 void DumpRenderTreeSupportQt::evaluateScriptInIsolatedWorld(QWebFrame* frame, int worldID, const QString& script)
866 {
867     QWebScriptWorld* scriptWorld;
868     if (!worldID) {
869         scriptWorld = new QWebScriptWorld();
870     } else if (!m_worldMap.contains(worldID)) {
871         scriptWorld = new QWebScriptWorld();
872         m_worldMap.insert(worldID, scriptWorld);
873     } else
874         scriptWorld = m_worldMap.value(worldID);
875
876     WebCore::Frame* coreFrame = QWebFramePrivate::core(frame);
877
878     ScriptController* proxy = coreFrame->script();
879
880     if (!proxy)
881         return;
882 #if USE(JSC)
883     proxy->executeScriptInWorld(scriptWorld->world(), script, true);
884 #elif USE(V8)
885     ScriptSourceCode source(script);
886     Vector<ScriptSourceCode> sources;
887     sources.append(source);
888     proxy->evaluateInIsolatedWorld(0, sources, true);
889 #endif
890 }
891
892 bool DumpRenderTreeSupportQt::isPageBoxVisible(QWebFrame* frame, int pageIndex)
893 {
894     WebCore::Frame* coreFrame = QWebFramePrivate::core(frame);
895     return coreFrame->document()->isPageBoxVisible(pageIndex);
896 }
897
898 QString DumpRenderTreeSupportQt::pageSizeAndMarginsInPixels(QWebFrame* frame, int pageIndex, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft)
899 {
900     WebCore::Frame* coreFrame = QWebFramePrivate::core(frame);
901     return PrintContext::pageSizeAndMarginsInPixels(coreFrame, pageIndex, width, height,
902                                                     marginTop, marginRight, marginBottom, marginLeft);
903 }
904
905 QString DumpRenderTreeSupportQt::pageProperty(QWebFrame* frame, const QString& propertyName, int pageNumber)
906 {
907     WebCore::Frame* coreFrame = QWebFramePrivate::core(frame);
908     return PrintContext::pageProperty(coreFrame, propertyName.toUtf8().constData(), pageNumber);
909 }
910
911 void DumpRenderTreeSupportQt::addUserStyleSheet(QWebPage* page, const QString& sourceCode)
912 {
913     page->handle()->page->group().addUserStyleSheetToWorld(mainThreadNormalWorld(), sourceCode, QUrl(), 0, 0, WebCore::InjectInAllFrames);
914 }
915
916 void DumpRenderTreeSupportQt::simulateDesktopNotificationClick(const QString& title)
917 {
918 #if ENABLE(NOTIFICATIONS)
919     NotificationPresenterClientQt::notificationPresenter()->notificationClicked(title);
920 #endif
921 }
922
923 QString DumpRenderTreeSupportQt::plainText(const QVariant& range)
924 {
925     QMap<QString, QVariant> map = range.toMap();
926     QVariant startContainer  = map.value(QLatin1String("startContainer"));
927     map = startContainer.toMap();
928
929     return map.value(QLatin1String("innerText")).toString();
930 }
931
932 QVariantList DumpRenderTreeSupportQt::nodesFromRect(const QWebElement& document, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping)
933 {
934     QVariantList res;
935     WebCore::Element* webElement = document.m_element;
936     if (!webElement)
937         return res;
938
939     Document* doc = webElement->document();
940     if (!doc)
941         return res;
942     RefPtr<NodeList> nodes = doc->nodesFromRect(x, y, top, right, bottom, left, ignoreClipping);
943     for (int i = 0; i < nodes->length(); i++) {
944         // QWebElement will be null if the Node is not an HTML Element
945         if (nodes->item(i)->isHTMLElement())
946             res << QVariant::fromValue(QWebElement(nodes->item(i)));
947         else
948             res << QVariant::fromValue(QDRTNode(nodes->item(i)));
949     }
950     return res;
951 }
952
953 // API Candidate?
954 QString DumpRenderTreeSupportQt::responseMimeType(QWebFrame* frame)
955 {
956     WebCore::Frame* coreFrame = QWebFramePrivate::core(frame);
957     WebCore::DocumentLoader* docLoader = coreFrame->loader()->documentLoader();
958     return docLoader->responseMIMEType();
959 }
960
961 void DumpRenderTreeSupportQt::clearOpener(QWebFrame* frame)
962 {
963     WebCore::Frame* coreFrame = QWebFramePrivate::core(frame);
964     coreFrame->loader()->setOpener(0);
965 }
966
967 void DumpRenderTreeSupportQt::addURLToRedirect(const QString& origin, const QString& destination)
968 {
969     FrameLoaderClientQt::URLsToRedirect[origin] = destination;
970 }
971
972 static QStringList iterateContextMenu(QMenu* menu)
973 {
974     if (!menu)
975         return QStringList();
976
977     QStringList items;
978     QList<QAction *> actions = menu->actions();
979     for (int i = 0; i < actions.count(); ++i) {
980         if (actions.at(i)->isSeparator())
981             items << QLatin1String("<separator>");
982         else
983             items << actions.at(i)->text();
984         if (actions.at(i)->menu())
985             items << iterateContextMenu(actions.at(i)->menu());
986     }
987     return items;
988 }
989
990 QStringList DumpRenderTreeSupportQt::contextMenu(QWebPage* page)
991 {
992 #ifndef QT_NO_CONTEXTMENU
993     return iterateContextMenu(page->d->currentContextMenu);
994 #else
995     return QStringList();
996 #endif
997 }
998
999 double DumpRenderTreeSupportQt::defaultMinimumTimerInterval()
1000 {
1001     return Settings::defaultMinDOMTimerInterval();
1002 }
1003
1004 void DumpRenderTreeSupportQt::setMinimumTimerInterval(QWebPage* page, double interval)
1005 {
1006     Page* corePage = QWebPagePrivate::core(page);
1007     if (!corePage)
1008         return;
1009
1010     corePage->settings()->setMinDOMTimerInterval(interval);
1011 }
1012
1013 QUrl DumpRenderTreeSupportQt::mediaContentUrlByElementId(QWebFrame* frame, const QString& elementId)
1014 {
1015     QUrl res;
1016
1017 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
1018     Frame* coreFrame = QWebFramePrivate::core(frame);
1019     if (!coreFrame)
1020         return res;
1021
1022     Document* doc = coreFrame->document();
1023     if (!doc)
1024         return res;
1025
1026     Node* coreNode = doc->getElementById(elementId);
1027     if (!coreNode)
1028         return res;
1029
1030     HTMLVideoElement* videoElement = static_cast<HTMLVideoElement*>(coreNode);
1031     PlatformMedia platformMedia = videoElement->platformMedia();
1032     if (platformMedia.type != PlatformMedia::QtMediaPlayerType)
1033         return res;
1034
1035     MediaPlayerPrivateQt* mediaPlayerQt = static_cast<MediaPlayerPrivateQt*>(platformMedia.media.qtMediaPlayer);
1036     if (mediaPlayerQt && mediaPlayerQt->mediaPlayer())
1037         res = mediaPlayerQt->mediaPlayer()->media().canonicalUrl();
1038 #endif
1039
1040     return res;
1041 }
1042
1043 // API Candidate?
1044 void DumpRenderTreeSupportQt::setAlternateHtml(QWebFrame* frame, const QString& html, const QUrl& baseUrl, const QUrl& failingUrl)
1045 {
1046     KURL kurl(baseUrl);
1047     WebCore::Frame* coreFrame = QWebFramePrivate::core(frame);
1048     WebCore::ResourceRequest request(kurl);
1049     const QByteArray utf8 = html.toUtf8();
1050     WTF::RefPtr<WebCore::SharedBuffer> data = WebCore::SharedBuffer::create(utf8.constData(), utf8.length());
1051     WebCore::SubstituteData substituteData(data, WTF::String("text/html"), WTF::String("utf-8"), failingUrl);
1052     coreFrame->loader()->load(request, substituteData, false);
1053 }
1054
1055 // Provide a backward compatibility with previously exported private symbols as of QtWebKit 4.6 release
1056
1057 void QWEBKIT_EXPORT qt_resumeActiveDOMObjects(QWebFrame* frame)
1058 {
1059     DumpRenderTreeSupportQt::resumeActiveDOMObjects(frame);
1060 }
1061
1062 void QWEBKIT_EXPORT qt_suspendActiveDOMObjects(QWebFrame* frame)
1063 {
1064     DumpRenderTreeSupportQt::suspendActiveDOMObjects(frame);
1065 }
1066
1067 void QWEBKIT_EXPORT qt_drt_clearFrameName(QWebFrame* frame)
1068 {
1069     DumpRenderTreeSupportQt::clearFrameName(frame);
1070 }
1071
1072 void QWEBKIT_EXPORT qt_drt_garbageCollector_collect()
1073 {
1074     DumpRenderTreeSupportQt::garbageCollectorCollect();
1075 }
1076
1077 void QWEBKIT_EXPORT qt_drt_garbageCollector_collectOnAlternateThread(bool waitUntilDone)
1078 {
1079     DumpRenderTreeSupportQt::garbageCollectorCollectOnAlternateThread(waitUntilDone);
1080 }
1081
1082 int QWEBKIT_EXPORT qt_drt_javaScriptObjectsCount()
1083 {
1084     return DumpRenderTreeSupportQt::javaScriptObjectsCount();
1085 }
1086
1087 int QWEBKIT_EXPORT qt_drt_numberOfActiveAnimations(QWebFrame* frame)
1088 {
1089     return DumpRenderTreeSupportQt::numberOfActiveAnimations(frame);
1090 }
1091
1092 void QWEBKIT_EXPORT qt_drt_overwritePluginDirectories()
1093 {
1094     DumpRenderTreeSupportQt::overwritePluginDirectories();
1095 }
1096
1097 bool QWEBKIT_EXPORT qt_drt_pauseAnimation(QWebFrame* frame, const QString& animationName, double time, const QString& elementId)
1098 {
1099     return DumpRenderTreeSupportQt::pauseAnimation(frame, animationName, time, elementId);
1100 }
1101
1102 bool QWEBKIT_EXPORT qt_drt_pauseTransitionOfProperty(QWebFrame* frame, const QString& propertyName, double time, const QString &elementId)
1103 {
1104     return DumpRenderTreeSupportQt::pauseTransitionOfProperty(frame, propertyName, time, elementId);
1105 }
1106
1107 void QWEBKIT_EXPORT qt_drt_resetOriginAccessWhiteLists()
1108 {
1109     DumpRenderTreeSupportQt::resetOriginAccessWhiteLists();
1110 }
1111
1112 void QWEBKIT_EXPORT qt_drt_run(bool b)
1113 {
1114     DumpRenderTreeSupportQt::setDumpRenderTreeModeEnabled(b);
1115 }
1116
1117 void QWEBKIT_EXPORT qt_drt_setJavaScriptProfilingEnabled(QWebFrame* frame, bool enabled)
1118 {
1119     DumpRenderTreeSupportQt::setJavaScriptProfilingEnabled(frame, enabled);
1120 }
1121
1122 void QWEBKIT_EXPORT qt_drt_whiteListAccessFromOrigin(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains)
1123 {
1124     DumpRenderTreeSupportQt::whiteListAccessFromOrigin(sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains);
1125 }
1126
1127 QString QWEBKIT_EXPORT qt_webpage_groupName(QWebPage* page)
1128 {
1129     return DumpRenderTreeSupportQt::webPageGroupName(page);
1130 }
1131
1132 void QWEBKIT_EXPORT qt_webpage_setGroupName(QWebPage* page, const QString& groupName)
1133 {
1134     DumpRenderTreeSupportQt::webPageSetGroupName(page, groupName);
1135 }
1136
1137 void QWEBKIT_EXPORT qt_dump_frame_loader(bool b)
1138 {
1139     DumpRenderTreeSupportQt::dumpFrameLoader(b);
1140 }
1141
1142 void QWEBKIT_EXPORT qt_dump_resource_load_callbacks(bool b)
1143 {
1144     DumpRenderTreeSupportQt::dumpResourceLoadCallbacks(b);
1145 }
1146
1147 void QWEBKIT_EXPORT qt_dump_editing_callbacks(bool b)
1148 {
1149     DumpRenderTreeSupportQt::dumpEditingCallbacks(b);
1150 }
1151
1152 void QWEBKIT_EXPORT qt_dump_set_accepts_editing(bool b)
1153 {
1154     DumpRenderTreeSupportQt::dumpSetAcceptsEditing(b);
1155 }
1156