summaryrefslogtreecommitdiffstats
path: root/WebKitTools/DumpRenderTree/qt
diff options
context:
space:
mode:
Diffstat (limited to 'WebKitTools/DumpRenderTree/qt')
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro25
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp (renamed from WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp)144
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h (renamed from WebKitTools/DumpRenderTree/qt/DumpRenderTree.h)29
-rw-r--r--WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp249
-rw-r--r--WebKitTools/DumpRenderTree/qt/EventSenderQt.h30
-rw-r--r--WebKitTools/DumpRenderTree/qt/GCControllerQt.cpp (renamed from WebKitTools/DumpRenderTree/qt/jsobjects.cpp)12
-rw-r--r--WebKitTools/DumpRenderTree/qt/GCControllerQt.h (renamed from WebKitTools/DumpRenderTree/qt/jsobjects.h)4
-rw-r--r--WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp125
-rw-r--r--WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h24
-rw-r--r--WebKitTools/DumpRenderTree/qt/WorkQueueItemQt.cpp2
-rw-r--r--WebKitTools/DumpRenderTree/qt/WorkQueueItemQt.h (renamed from WebKitTools/DumpRenderTree/qt/WorkQueueItem.h)12
-rw-r--r--WebKitTools/DumpRenderTree/qt/main.cpp35
12 files changed, 568 insertions, 123 deletions
diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro
index 81e929b..ad42bdd 100644
--- a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro
+++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro
@@ -17,29 +17,32 @@ INCLUDEPATH += ../../../JavaScriptCore/ForwardingHeaders
INCLUDEPATH += $$BASEDIR
DESTDIR = ../../../bin
-CONFIG += link_pkgconfig
-PKGCONFIG += fontconfig
+!win32 {
+ CONFIG += link_pkgconfig
+ PKGCONFIG += fontconfig
+}
-QT = core gui network
+QT = core gui network testlib
macx: QT += xml
HEADERS = $$BASEDIR/WorkQueue.h \
- WorkQueueItem.h \
- DumpRenderTree.h \
+ DumpRenderTreeQt.h \
EventSenderQt.h \
TextInputControllerQt.h \
+ WorkQueueItemQt.h \
LayoutTestControllerQt.h \
- jsobjects.h \
+ GCControllerQt.h \
testplugin.h
-SOURCES = $$BASEDIR/WorkQueue.cpp \
- DumpRenderTree.cpp \
+SOURCES = ../../../JavaScriptCore/wtf/Assertions.cpp \
+ $$BASEDIR/WorkQueue.cpp \
+ DumpRenderTreeQt.cpp \
EventSenderQt.cpp \
TextInputControllerQt.cpp \
WorkQueueItemQt.cpp \
LayoutTestControllerQt.cpp \
- main.cpp \
- jsobjects.cpp \
- testplugin.cpp
+ GCControllerQt.cpp \
+ testplugin.cpp \
+ main.cpp
unix:!mac {
QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR
diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp
index 6d466bf..9916f24 100644
--- a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp
+++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp
@@ -31,11 +31,11 @@
#include "config.h"
-#include "DumpRenderTree.h"
+#include "DumpRenderTreeQt.h"
#include "EventSenderQt.h"
+#include "GCControllerQt.h"
#include "LayoutTestControllerQt.h"
#include "TextInputControllerQt.h"
-#include "jsobjects.h"
#include "testplugin.h"
#include "WorkQueue.h"
@@ -48,6 +48,7 @@
#include <QFileInfo>
#include <QFocusEvent>
#include <QFontDatabase>
+#include <QLocale>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
@@ -66,7 +67,10 @@
#include <limits.h>
+#ifndef Q_OS_WIN
#include <unistd.h>
+#endif
+
#include <qdebug.h>
extern void qt_drt_run(bool b);
@@ -86,13 +90,13 @@ const unsigned int maxViewHeight = 600;
NetworkAccessManager::NetworkAccessManager(QObject* parent)
: QNetworkAccessManager(parent)
{
-#ifndef QT_NO_SSL
+#ifndef QT_NO_OPENSSL
connect(this, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)),
this, SLOT(sslErrorsEncountered(QNetworkReply*, const QList<QSslError>&)));
#endif
}
-#ifndef QT_NO_SSL
+#ifndef QT_NO_OPENSSL
void NetworkAccessManager::sslErrorsEncountered(QNetworkReply* reply, const QList<QSslError>& errors)
{
if (reply->url().host() == "127.0.0.1" || reply->url().host() == "localhost") {
@@ -158,7 +162,6 @@ void WebPage::resetSettings()
{
// After each layout test, reset the settings that may have been changed by
// layoutTestController.overridePreference() or similar.
-
settings()->resetFontSize(QWebSettings::DefaultFontSize);
settings()->resetAttribute(QWebSettings::JavascriptCanOpenWindows);
settings()->resetAttribute(QWebSettings::JavascriptEnabled);
@@ -166,7 +169,12 @@ void WebPage::resetSettings()
settings()->resetAttribute(QWebSettings::LinksIncludedInFocusChain);
settings()->resetAttribute(QWebSettings::OfflineWebApplicationCacheEnabled);
settings()->resetAttribute(QWebSettings::LocalContentCanAccessRemoteUrls);
+
+ // globalSettings must be reset explicitly.
+ m_drt->layoutTestController()->setXSSAuditorEnabled(false);
+
QWebSettings::setMaximumPagesInCache(0); // reset to default
+ settings()->setUserStyleSheetUrl(QUrl()); // reset to default
}
QWebPage *WebPage::createWindow(QWebPage::WebWindowType)
@@ -305,8 +313,8 @@ QObject* WebPage::createPlugin(const QString& classId, const QUrl& url, const QS
DumpRenderTree::DumpRenderTree()
: m_dumpPixels(false)
, m_stdin(0)
- , m_notifier(0)
, m_enableTextOutput(false)
+ , m_singleFileMode(false)
{
qt_drt_overwritePluginDirectories();
QWebSettings::enablePersistentStorage();
@@ -317,9 +325,12 @@ DumpRenderTree::DumpRenderTree()
m_page = new WebPage(m_mainView, this);
m_mainView->setPage(m_page);
- // create out controllers. This has to be done before connectFrame,
+ // create our controllers. This has to be done before connectFrame,
// as it exports there to the JavaScript DOM window.
m_controller = new LayoutTestController(this);
+ connect(m_controller, SIGNAL(showPage()), this, SLOT(showPage()));
+ connect(m_controller, SIGNAL(hidePage()), this, SLOT(hidePage()));
+
connect(m_controller, SIGNAL(done()), this, SLOT(dump()));
m_eventSender = new EventSender(m_page);
m_textInputController = new TextInputController(m_page);
@@ -332,6 +343,11 @@ DumpRenderTree::DumpRenderTree()
connect(m_page, SIGNAL(loadFinished(bool)),
m_controller, SLOT(maybeDump(bool)));
+ // We need to connect to loadStarted() because notifyDone should only
+ // dump results itself when the last page loaded in the test has finished loading.
+ connect(m_page, SIGNAL(loadStarted()),
+ m_controller, SLOT(resetLoadFinished()));
+ connect(m_page, SIGNAL(windowCloseRequested()), this, SLOT(windowCloseRequested()));
connect(m_page->mainFrame(), SIGNAL(titleChanged(const QString&)),
SLOT(titleChanged(const QString&)));
@@ -350,20 +366,6 @@ DumpRenderTree::~DumpRenderTree()
{
delete m_mainView;
delete m_stdin;
- delete m_notifier;
-}
-
-void DumpRenderTree::open()
-{
- if (!m_stdin) {
- m_stdin = new QFile;
- m_stdin->open(stdin, QFile::ReadOnly);
- }
-
- if (!m_notifier) {
- m_notifier = new QSocketNotifier(STDIN_FILENO, QSocketNotifier::Read);
- connect(m_notifier, SIGNAL(activated(int)), this, SLOT(readStdin(int)));
- }
}
static void clearHistory(QWebPage* page)
@@ -438,6 +440,7 @@ void DumpRenderTree::open(const QUrl& aurl)
QFocusEvent ev(QEvent::FocusIn);
m_page->event(&ev);
+ QWebSettings::clearMemoryCaches();
QFontDatabase::removeAllApplicationFonts();
#if defined(Q_WS_X11)
initializeFonts();
@@ -448,20 +451,59 @@ void DumpRenderTree::open(const QUrl& aurl)
m_page->mainFrame()->load(url);
}
-void DumpRenderTree::readStdin(int /* socket */)
+void DumpRenderTree::readLine()
+{
+ if (!m_stdin) {
+ m_stdin = new QFile;
+ m_stdin->open(stdin, QFile::ReadOnly);
+
+ if (!m_stdin->isReadable()) {
+ emit quit();
+ return;
+ }
+ }
+
+ QByteArray line = m_stdin->readLine().trimmed();
+
+ if (line.isEmpty()) {
+ emit quit();
+ return;
+ }
+
+ processLine(QString::fromLocal8Bit(line.constData(), line.length()));
+}
+
+void DumpRenderTree::processLine(const QString &input)
{
- // Read incoming data from stdin...
- QByteArray line = m_stdin->readLine();
- if (line.endsWith('\n'))
- line.truncate(line.size()-1);
- //fprintf(stderr, "\n opening %s\n", line.constData());
- if (line.isEmpty())
- quit();
+ QString line = input;
- if (line.startsWith("http:") || line.startsWith("https:"))
+ if (line.startsWith(QLatin1String("http:"))
+ || line.startsWith(QLatin1String("https:"))
+ || line.startsWith(QLatin1String("file:"))) {
open(QUrl(line));
- else {
+ } else {
QFileInfo fi(line);
+
+ if (!fi.exists()) {
+ QDir currentDir = QDir::currentPath();
+
+ // Try to be smart about where the test is located
+ if (currentDir.dirName() == QLatin1String("LayoutTests"))
+ fi = QFileInfo(currentDir, line.replace(QRegExp(".*?LayoutTests/(.*)"), "\\1"));
+ else if (!line.contains(QLatin1String("LayoutTests")))
+ fi = QFileInfo(currentDir, line.prepend(QLatin1String("LayoutTests/")));
+
+ if (!fi.exists()) {
+ if (isSingleFileMode())
+ emit quit();
+ else
+ emit ready();
+
+ return;
+ }
+
+ }
+
open(QUrl::fromLocalFile(fi.absoluteFilePath()));
}
@@ -490,6 +532,18 @@ void DumpRenderTree::initJSObjects()
frame->addToJavaScriptWindowObject(QLatin1String("GCController"), m_gcController);
}
+void DumpRenderTree::showPage()
+{
+ m_mainView->show();
+ // we need a paint event but cannot process all the events
+ QPixmap pixmap(m_mainView->size());
+ m_mainView->render(&pixmap);
+}
+
+void DumpRenderTree::hidePage()
+{
+ m_mainView->hide();
+}
QString DumpRenderTree::dumpFramesAsText(QWebFrame* frame)
{
@@ -602,11 +656,12 @@ static const char *methodNameStringForFailedTest(LayoutTestController *controlle
void DumpRenderTree::dump()
{
+ // Prevent any further frame load callbacks from appearing after we dump the result.
+ qt_dump_frame_loader(false);
+
QWebFrame *mainFrame = m_page->mainFrame();
- //fprintf(stderr, " Dumping\n");
- if (!m_notifier) {
- // Dump markup in single file mode...
+ if (isSingleFileMode()) {
QString markup = mainFrame->toHtml();
fprintf(stdout, "Source:\n\n%s\n", markup.toUtf8().constData());
}
@@ -684,8 +739,10 @@ void DumpRenderTree::dump()
fflush(stdout);
fflush(stderr);
- if (!m_notifier)
- quit(); // Exit now in single file mode...
+ if (isSingleFileMode())
+ emit quit();
+ else
+ emit ready();
}
void DumpRenderTree::titleChanged(const QString &s)
@@ -741,15 +798,30 @@ QWebPage *DumpRenderTree::createWindow()
connect(page, SIGNAL(frameCreated(QWebFrame*)), this, SLOT(connectFrame(QWebFrame*)));
connectFrame(page->mainFrame());
connect(page, SIGNAL(loadFinished(bool)), m_controller, SLOT(maybeDump(bool)));
+ connect(page, SIGNAL(windowCloseRequested()), this, SLOT(windowCloseRequested()));
return page;
}
+void DumpRenderTree::windowCloseRequested()
+{
+ QWebPage* page = qobject_cast<QWebPage*>(sender());
+ QObject* container = page->parent();
+ windows.removeAll(container);
+ container->deleteLater();
+}
+
int DumpRenderTree::windowCount() const
{
// include the main view in the count
return windows.count() + 1;
}
+void DumpRenderTree::switchFocus(bool focused)
+{
+ QFocusEvent event((focused) ? QEvent::FocusIn : QEvent::FocusOut, Qt::ActiveWindowFocusReason);
+ QApplication::sendEvent(m_mainView, &event);
+}
+
#if defined(Q_WS_X11)
void DumpRenderTree::initializeFonts()
{
diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.h b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h
index ab229fe..00d7ae4 100644
--- a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.h
+++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h
@@ -27,8 +27,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DUMPRENDERTREE_H
-#define DUMPRENDERTREE_H
+#ifndef DumpRenderTreeQt_h
+#define DumpRenderTreeQt_h
#include <QList>
#include <QNetworkAccessManager>
@@ -36,7 +36,7 @@
#include <QTextStream>
#include <QSocketNotifier>
-#ifndef QT_NO_SSL
+#ifndef QT_NO_OPENSSL
#include <QSslError>
#endif
@@ -68,15 +68,15 @@ public:
DumpRenderTree();
virtual ~DumpRenderTree();
- // Initialize in multi-file mode, used by run-webkit-tests.
- void open();
-
// Initialize in single-file mode.
void open(const QUrl& url);
void setTextOutputEnabled(bool enable) { m_enableTextOutput = enable; }
bool isTextOutputEnabled() { return m_enableTextOutput; }
+ void setSingleFileMode(bool flag) { m_singleFileMode = flag; }
+ bool isSingleFileMode() { return m_singleFileMode; }
+
void setDumpPixels(bool);
void closeRemainingWindows();
@@ -89,6 +89,8 @@ public:
QWebPage *createWindow();
int windowCount() const;
+ void switchFocus(bool focused);
+
WebPage *webPage() const { return m_page; }
@@ -98,15 +100,24 @@ public:
public Q_SLOTS:
void initJSObjects();
- void readStdin(int);
+
+ void readLine();
+ void processLine(const QString&);
+
void dump();
void titleChanged(const QString &s);
void connectFrame(QWebFrame *frame);
void dumpDatabaseQuota(QWebFrame* frame, const QString& dbName);
void statusBarMessage(const QString& message);
+ void windowCloseRequested();
Q_SIGNALS:
void quit();
+ void ready();
+
+private Q_SLOTS:
+ void showPage();
+ void hidePage();
private:
QString dumpFramesAsText(QWebFrame* frame);
@@ -124,10 +135,10 @@ private:
GCController* m_gcController;
QFile *m_stdin;
- QSocketNotifier* m_notifier;
QList<QObject*> windows;
bool m_enableTextOutput;
+ bool m_singleFileMode;
};
class NetworkAccessManager : public QNetworkAccessManager {
@@ -136,7 +147,7 @@ public:
NetworkAccessManager(QObject* parent);
private slots:
-#ifndef QT_NO_SSL
+#ifndef QT_NO_OPENSSL
void sslErrorsEncountered(QNetworkReply*, const QList<QSslError>&);
#endif
};
diff --git a/WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp b/WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp
index a0da273..73a9934 100644
--- a/WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp
+++ b/WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp
@@ -31,6 +31,8 @@
//#include <QtDebug>
+#include <QtTest/QtTest>
+
#define KEYCODE_DEL 127
#define KEYCODE_BACKSPACE 8
#define KEYCODE_LEFTARROW 0xf702
@@ -38,11 +40,34 @@
#define KEYCODE_UPARROW 0xf700
#define KEYCODE_DOWNARROW 0xf701
+// Ports like Gtk and Windows expose a different approach for their zooming
+// API if compared to Qt: they have specific methods for zooming in and out,
+// as well as a settable zoom factor, while Qt has only a 'setZoomValue' method.
+// Hence Qt DRT adopts a fixed zoom-factor (1.2) for compatibility.
+#define ZOOM_STEP 1.2
+
+#define DRT_MESSAGE_DONE (QEvent::User + 1)
+
+struct DRTEventQueue {
+ QEvent* m_event;
+ int m_delay;
+};
+
+static DRTEventQueue eventQueue[1024];
+static unsigned endOfQueue;
+static unsigned startOfQueue;
EventSender::EventSender(QWebPage* parent)
: QObject(parent)
{
m_page = parent;
+ m_mouseButtonPressed = false;
+ m_drag = false;
+ memset(eventQueue, 0, sizeof(eventQueue));
+ endOfQueue = 0;
+ startOfQueue = 0;
+ m_eventLoop = 0;
+ m_page->view()->installEventFilter(this);
}
void EventSender::mouseDown(int button)
@@ -67,9 +92,11 @@ void EventSender::mouseDown(int button)
break;
}
+ m_mouseButtons |= mouseButton;
+
// qDebug() << "EventSender::mouseDown" << frame;
- QMouseEvent event(QEvent::MouseButtonPress, m_mousePos, mouseButton, mouseButton, Qt::NoModifier);
- QApplication::sendEvent(m_page, &event);
+ QMouseEvent* event = new QMouseEvent(QEvent::MouseButtonPress, m_mousePos, m_mousePos, mouseButton, m_mouseButtons, Qt::NoModifier);
+ sendOrQueueEvent(event);
}
void EventSender::mouseUp(int button)
@@ -94,26 +121,28 @@ void EventSender::mouseUp(int button)
break;
}
+ m_mouseButtons &= ~mouseButton;
+
// qDebug() << "EventSender::mouseUp" << frame;
- QMouseEvent event(QEvent::MouseButtonRelease, m_mousePos, mouseButton, mouseButton, Qt::NoModifier);
- QApplication::sendEvent(m_page, &event);
+ QMouseEvent* event = new QMouseEvent(QEvent::MouseButtonRelease, m_mousePos, m_mousePos, mouseButton, m_mouseButtons, Qt::NoModifier);
+ sendOrQueueEvent(event);
}
void EventSender::mouseMoveTo(int x, int y)
{
// qDebug() << "EventSender::mouseMoveTo" << x << y;
m_mousePos = QPoint(x, y);
- QMouseEvent event(QEvent::MouseMove, m_mousePos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
- QApplication::sendEvent(m_page, &event);
+ QMouseEvent* event = new QMouseEvent(QEvent::MouseMove, m_mousePos, m_mousePos, Qt::NoButton, m_mouseButtons, Qt::NoModifier);
+ sendOrQueueEvent(event);
}
void EventSender::leapForward(int ms)
{
- m_timeLeap += ms;
+ eventQueue[endOfQueue].m_delay = ms;
//qDebug() << "EventSender::leapForward" << ms;
}
-void EventSender::keyDown(const QString& string, const QStringList& modifiers)
+void EventSender::keyDown(const QString& string, const QStringList& modifiers, unsigned int location)
{
QString s = string;
Qt::KeyboardModifiers modifs = 0;
@@ -128,12 +157,16 @@ void EventSender::keyDown(const QString& string, const QStringList& modifiers)
else if (m == "metaKey")
modifs |= Qt::MetaModifier;
}
+ if (location == 3)
+ modifs |= Qt::KeypadModifier;
int code = 0;
if (string.length() == 1) {
code = string.unicode()->unicode();
//qDebug() << ">>>>>>>>> keyDown" << code << (char)code;
// map special keycodes used by the tests to something that works for Qt/X11
- if (code == '\t') {
+ if (code == '\r') {
+ code = Qt::Key_Return;
+ } else if (code == '\t') {
code = Qt::Key_Tab;
if (modifs == Qt::ShiftModifier)
code = Qt::Key_Backtab;
@@ -251,6 +284,131 @@ void EventSender::scheduleAsynchronousClick()
QApplication::postEvent(m_page, event2);
}
+void EventSender::addTouchPoint(int x, int y)
+{
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ int id = m_touchPoints.count();
+ QTouchEvent::TouchPoint point(id);
+ m_touchPoints.append(point);
+ updateTouchPoint(id, x, y);
+ m_touchPoints[id].setState(Qt::TouchPointPressed);
+#endif
+}
+
+void EventSender::updateTouchPoint(int index, int x, int y)
+{
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ if (index < 0 || index >= m_touchPoints.count())
+ return;
+
+ QTouchEvent::TouchPoint &p = m_touchPoints[index];
+ p.setPos(QPointF(x, y));
+ p.setState(Qt::TouchPointMoved);
+#endif
+}
+
+void EventSender::setTouchModifier(const QString &modifier, bool enable)
+{
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ Qt::KeyboardModifier mod = Qt::NoModifier;
+ if (!modifier.compare(QLatin1String("shift"), Qt::CaseInsensitive))
+ mod = Qt::ShiftModifier;
+ else if (!modifier.compare(QLatin1String("alt"), Qt::CaseInsensitive))
+ mod = Qt::AltModifier;
+ else if (!modifier.compare(QLatin1String("meta"), Qt::CaseInsensitive))
+ mod = Qt::MetaModifier;
+ else if (!modifier.compare(QLatin1String("ctrl"), Qt::CaseInsensitive))
+ mod = Qt::ControlModifier;
+
+ if (enable)
+ m_touchModifiers |= mod;
+ else
+ m_touchModifiers &= ~mod;
+#endif
+}
+
+void EventSender::touchStart()
+{
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ if (!m_touchActive) {
+ sendTouchEvent(QEvent::TouchBegin);
+ m_touchActive = true;
+ } else
+ sendTouchEvent(QEvent::TouchUpdate);
+#endif
+}
+
+void EventSender::touchMove()
+{
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ sendTouchEvent(QEvent::TouchUpdate);
+#endif
+}
+
+void EventSender::touchEnd()
+{
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ for (int i = 0; i < m_touchPoints.count(); ++i)
+ if (m_touchPoints[i].state() != Qt::TouchPointReleased) {
+ sendTouchEvent(QEvent::TouchUpdate);
+ return;
+ }
+ sendTouchEvent(QEvent::TouchEnd);
+ m_touchActive = false;
+#endif
+}
+
+void EventSender::clearTouchPoints()
+{
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ m_touchPoints.clear();
+ m_touchModifiers = Qt::KeyboardModifiers();
+ m_touchActive = false;
+#endif
+}
+
+void EventSender::releaseTouchPoint(int index)
+{
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ if (index < 0 || index >= m_touchPoints.count())
+ return;
+
+ m_touchPoints[index].setState(Qt::TouchPointReleased);
+#endif
+}
+
+void EventSender::sendTouchEvent(QEvent::Type type)
+{
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ QTouchEvent event(type, QTouchEvent::TouchScreen, m_touchModifiers);
+ event.setTouchPoints(m_touchPoints);
+ QApplication::sendEvent(m_page, &event);
+ QList<QTouchEvent::TouchPoint>::Iterator it = m_touchPoints.begin();
+ while (it != m_touchPoints.end()) {
+ if (it->state() == Qt::TouchPointReleased)
+ it = m_touchPoints.erase(it);
+ else {
+ it->setState(Qt::TouchPointStationary);
+ ++it;
+ }
+ }
+#endif
+}
+
+void EventSender::zoomPageIn()
+{
+ QWebFrame* frame = m_page->mainFrame();
+ if (frame)
+ frame->setZoomFactor(frame->zoomFactor() * ZOOM_STEP);
+}
+
+void EventSender::zoomPageOut()
+{
+ QWebFrame* frame = m_page->mainFrame();
+ if (frame)
+ frame->setZoomFactor(frame->zoomFactor() / ZOOM_STEP);
+}
+
QWebFrame* EventSender::frameUnderMouse() const
{
QWebFrame* frame = m_page->mainFrame();
@@ -267,3 +425,76 @@ redo:
return frame;
return 0;
}
+
+void EventSender::sendOrQueueEvent(QEvent* event)
+{
+ // Mouse move events are queued if
+ // 1. A previous event was queued.
+ // 2. A delay was set-up by leapForward().
+ // 3. A call to mouseMoveTo while the mouse button is pressed could initiate a drag operation, and that does not return until mouseUp is processed.
+ // To be safe and avoid a deadlock, this event is queued.
+ if (endOfQueue == startOfQueue && !eventQueue[endOfQueue].m_delay && (!(m_mouseButtonPressed && (m_eventLoop && event->type() == QEvent::MouseButtonRelease)))) {
+ QApplication::sendEvent(m_page->view(), event);
+ delete event;
+ return;
+ }
+ eventQueue[endOfQueue++].m_event = event;
+ eventQueue[endOfQueue].m_delay = 0;
+ replaySavedEvents(event->type() != QEvent::MouseMove);
+}
+
+void EventSender::replaySavedEvents(bool flush)
+{
+ if (startOfQueue < endOfQueue) {
+ // First send all the events that are ready to be sent
+ while (!eventQueue[startOfQueue].m_delay && startOfQueue < endOfQueue) {
+ QEvent* ev = eventQueue[startOfQueue++].m_event;
+ QApplication::postEvent(m_page->view(), ev); // ev deleted by the system
+ }
+ if (startOfQueue == endOfQueue) {
+ // Reset the queue
+ startOfQueue = 0;
+ endOfQueue = 0;
+ } else {
+ QTest::qWait(eventQueue[startOfQueue].m_delay);
+ eventQueue[startOfQueue].m_delay = 0;
+ }
+ }
+ if (!flush)
+ return;
+
+ // Send a marker event, it will tell us when it is safe to exit the new event loop
+ QEvent* drtEvent = new QEvent((QEvent::Type)DRT_MESSAGE_DONE);
+ QApplication::postEvent(m_page->view(), drtEvent);
+
+ // Start an event loop for async handling of Drag & Drop
+ m_eventLoop = new QEventLoop;
+ m_eventLoop->exec();
+ delete m_eventLoop;
+ m_eventLoop = 0;
+}
+
+bool EventSender::eventFilter(QObject* watched, QEvent* event)
+{
+ if (watched != m_page->view())
+ return false;
+ switch (event->type()) {
+ case QEvent::Leave:
+ return true;
+ case QEvent::MouseButtonPress:
+ m_mouseButtonPressed = true;
+ break;
+ case QEvent::MouseMove:
+ if (m_mouseButtonPressed)
+ m_drag = true;
+ break;
+ case QEvent::MouseButtonRelease:
+ m_mouseButtonPressed = false;
+ m_drag = false;
+ break;
+ case DRT_MESSAGE_DONE:
+ m_eventLoop->exit();
+ return true;
+ }
+ return false;
+}
diff --git a/WebKitTools/DumpRenderTree/qt/EventSenderQt.h b/WebKitTools/DumpRenderTree/qt/EventSenderQt.h
index fd74455..f6cfc7c 100644
--- a/WebKitTools/DumpRenderTree/qt/EventSenderQt.h
+++ b/WebKitTools/DumpRenderTree/qt/EventSenderQt.h
@@ -31,6 +31,7 @@
#include <QApplication>
#include <QEvent>
+#include <QEventLoop>
#include <QMouseEvent>
#include <QObject>
#include <QPoint>
@@ -40,25 +41,52 @@
#include <qwebpage.h>
#include <qwebframe.h>
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+#include <QTouchEvent>
+#endif
+
class EventSender : public QObject {
Q_OBJECT
public:
EventSender(QWebPage* parent);
+ virtual bool eventFilter(QObject* watched, QEvent* event);
public slots:
void mouseDown(int button = 0);
void mouseUp(int button = 0);
void mouseMoveTo(int x, int y);
void leapForward(int ms);
- void keyDown(const QString& string, const QStringList& modifiers = QStringList());
+ void keyDown(const QString& string, const QStringList& modifiers = QStringList(), unsigned int location = 0);
void clearKillRing() {}
void contextClick();
void scheduleAsynchronousClick();
+ void addTouchPoint(int x, int y);
+ void updateTouchPoint(int index, int x, int y);
+ void setTouchModifier(const QString &modifier, bool enable);
+ void touchStart();
+ void touchMove();
+ void touchEnd();
+ void zoomPageIn();
+ void zoomPageOut();
+ void clearTouchPoints();
+ void releaseTouchPoint(int index);
private:
+ void sendTouchEvent(QEvent::Type);
+ void sendOrQueueEvent(QEvent*);
+ void replaySavedEvents(bool flush);
QPoint m_mousePos;
+ Qt::MouseButtons m_mouseButtons;
QWebPage* m_page;
int m_timeLeap;
+ bool m_mouseButtonPressed;
+ bool m_drag;
+ QEventLoop* m_eventLoop;
QWebFrame* frameUnderMouse() const;
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ QList<QTouchEvent::TouchPoint> m_touchPoints;
+ Qt::KeyboardModifiers m_touchModifiers;
+ bool m_touchActive;
+#endif
};
#endif // EventSenderQt_h
diff --git a/WebKitTools/DumpRenderTree/qt/jsobjects.cpp b/WebKitTools/DumpRenderTree/qt/GCControllerQt.cpp
index af331f0..9cc3aa7 100644
--- a/WebKitTools/DumpRenderTree/qt/jsobjects.cpp
+++ b/WebKitTools/DumpRenderTree/qt/GCControllerQt.cpp
@@ -28,20 +28,20 @@
*/
#include "config.h"
-#include "jsobjects.h"
+#include "GCControllerQt.h"
#include <qwebpage.h>
-GCController::GCController(QWebPage* parent)
- : QObject(parent)
-{
-}
-
extern int qt_drt_javaScriptObjectsCount();
extern void qt_drt_garbageCollector_collect();
extern void qt_drt_garbageCollector_collectOnAlternateThread(bool waitUntilDone);
+GCController::GCController(QWebPage* parent)
+ : QObject(parent)
+{
+}
+
void GCController::collect() const
{
qt_drt_garbageCollector_collect();
diff --git a/WebKitTools/DumpRenderTree/qt/jsobjects.h b/WebKitTools/DumpRenderTree/qt/GCControllerQt.h
index 3ee566b..8f5b432 100644
--- a/WebKitTools/DumpRenderTree/qt/jsobjects.h
+++ b/WebKitTools/DumpRenderTree/qt/GCControllerQt.h
@@ -26,8 +26,8 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef JSOBJECTS_H
-#define JSOBJECTS_H
+#ifndef GCControllerQt_h
+#define GCControllerQt_h
#include <QObject>
diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
index 0ea5632..9430ec7 100644
--- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
+++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
@@ -29,10 +29,12 @@
#include "config.h"
#include "LayoutTestControllerQt.h"
-#include "DumpRenderTree.h"
+#include "DumpRenderTreeQt.h"
#include "WorkQueue.h"
-#include "WorkQueueItem.h"
+#include "WorkQueueItemQt.h"
#include <QDir>
+#include <QLocale>
+#include <qwebsettings.h>
extern void qt_dump_editing_callbacks(bool b);
extern void qt_dump_resource_load_callbacks(bool b);
@@ -41,9 +43,11 @@ extern bool qt_drt_pauseAnimation(QWebFrame*, const QString& name, double time,
extern bool qt_drt_pauseTransitionOfProperty(QWebFrame*, const QString& name, double time, const QString& elementId);
extern bool qt_drt_pauseSVGAnimation(QWebFrame*, const QString& animationId, double time, const QString& elementId);
extern int qt_drt_numberOfActiveAnimations(QWebFrame*);
+extern void qt_drt_setDomainRelaxationForbiddenForURLScheme(bool forbidden, const QString& scheme);
extern void qt_drt_whiteListAccessFromOrigin(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains);
extern QString qt_drt_counterValueForElementById(QWebFrame* qFrame, const QString& id);
+extern int qt_drt_workerThreadCount();
LayoutTestController::LayoutTestController(WebCore::DumpRenderTree* drt)
: QObject()
@@ -54,7 +58,8 @@ LayoutTestController::LayoutTestController(WebCore::DumpRenderTree* drt)
void LayoutTestController::reset()
{
- m_isLoading = true;
+ m_hasDumped = false;
+ m_loadFinished = false;
m_textDump = false;
m_dumpBackForwardList = false;
m_dumpChildrenAsText = false;
@@ -67,8 +72,10 @@ void LayoutTestController::reset()
m_topLoadingFrame = 0;
m_waitForPolicy = false;
m_handleErrorPages = false;
+ m_webHistory = 0;
qt_dump_editing_callbacks(false);
qt_dump_resource_load_callbacks(false);
+ emit hidePage();
}
void LayoutTestController::processWork()
@@ -78,32 +85,40 @@ void LayoutTestController::processWork()
// if we didn't start a new load, then we finished all the commands, so we're ready to dump state
if (WorkQueue::shared()->processWork() && !shouldWaitUntilDone()) {
emit done();
- m_isLoading = false;
+ m_hasDumped = true;
}
}
-// Called on loadFinished on mainFrame.
+// Called on loadFinished on WebPage
void LayoutTestController::maybeDump(bool success)
{
- Q_ASSERT(sender() == m_topLoadingFrame->page());
+ // This can happen on any of the http/tests/security/window-events-*.html tests, where the test opens
+ // a new window, calls the unload and load event handlers on the window's page, and then immediately
+ // issues a notifyDone. Needs investigation.
+ if (!m_topLoadingFrame)
+ return;
+
+ // It is possible that we get called by windows created from the main page that have finished
+ // loading, so we don't ASSERT here. At the moment we do not gather results from such windows,
+ // but may need to in future.
+ if (sender() != m_topLoadingFrame->page())
+ return;
+
+ m_loadFinished = true;
// as the function is called on loadFinished, the test might
// already have dumped and thus no longer be active, thus
// bail out here.
- if (!m_isLoading)
+ if (m_hasDumped)
return;
- m_topLoadingFrame = 0;
WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
-
- if (!shouldWaitUntilDone()) {
- if (WorkQueue::shared()->count())
- QTimer::singleShot(0, this, SLOT(processWork()));
- else {
- if (success)
- emit done();
- m_isLoading = false;
- }
+ if (WorkQueue::shared()->count())
+ QTimer::singleShot(0, this, SLOT(processWork()));
+ else if (!shouldWaitUntilDone()) {
+ if (success)
+ emit done();
+ m_hasDumped = true;
}
}
@@ -119,9 +134,19 @@ QString LayoutTestController::counterValueForElementById(const QString& id)
return qt_drt_counterValueForElementById(m_drt->webPage()->mainFrame(), id);
}
+int LayoutTestController::webHistoryItemCount()
+{
+ if (!m_webHistory)
+ return -1;
+
+ // Subtract one here as our QWebHistory::count() includes the actual page,
+ // which is not considered in the DRT tests.
+ return m_webHistory->count() - 1;
+}
+
void LayoutTestController::keepWebHistory()
{
- // FIXME: implement
+ m_webHistory = m_drt->webPage()->history();
}
void LayoutTestController::notifyDone()
@@ -132,11 +157,19 @@ void LayoutTestController::notifyDone()
return;
m_timeoutTimer.stop();
+ m_waitForDone = false;
+
+ // If the page has not finished loading (i.e. loadFinished() has not been emitted) then
+ // content created by the likes of document.write() JS methods will not be available yet.
+ // When the page has finished loading, maybeDump above will dump the results now that we have
+ // just set shouldWaitUntilDone to false.
+ if (!m_loadFinished)
+ return;
+
emit done();
// FIXME: investigate why always resetting these result in timeouts
- m_isLoading = false;
- m_waitForDone = false;
+ m_hasDumped = true;
m_waitForPolicy = false;
}
@@ -145,6 +178,11 @@ int LayoutTestController::windowCount()
return m_drt->windowCount();
}
+void LayoutTestController::display()
+{
+ emit showPage();
+}
+
void LayoutTestController::clearBackForwardList()
{
m_drt->webPage()->history()->clear();
@@ -153,7 +191,7 @@ void LayoutTestController::clearBackForwardList()
QString LayoutTestController::pathToLocalResource(const QString& url)
{
// Function introduced in r28690.
- return QLatin1String("file://") + QUrl(url).toLocalFile();
+ return QDir::toNativeSeparators(url);
}
void LayoutTestController::dumpEditingCallbacks()
@@ -208,7 +246,7 @@ void LayoutTestController::queueNonLoadingScript(const QString& script)
void LayoutTestController::provisionalLoad()
{
QWebFrame* frame = qobject_cast<QWebFrame*>(sender());
- if (!m_topLoadingFrame && m_isLoading)
+ if (!m_topLoadingFrame && !m_hasDumped)
m_topLoadingFrame = frame;
}
@@ -280,6 +318,26 @@ void LayoutTestController::setPOSIXLocale(const QString& locale)
QLocale::setDefault(qlocale);
}
+void LayoutTestController::setWindowIsKey(bool isKey)
+{
+ m_drt->switchFocus(isKey);
+}
+
+void LayoutTestController::setMainFrameIsFirstResponder(bool isFirst)
+{
+ //FIXME: only need this for the moment: https://bugs.webkit.org/show_bug.cgi?id=32990
+}
+
+void LayoutTestController::setXSSAuditorEnabled(bool enable)
+{
+ // Set XSSAuditorEnabled globally so that windows created by the test inherit it too.
+ // resetSettings() will call this to reset the page and global setting to false again.
+ // Needed by http/tests/security/xssAuditor/link-opens-new-window.html
+ QWebSettings* globalSettings = QWebSettings::globalSettings();
+ globalSettings->setAttribute(QWebSettings::XSSAuditorEnabled, enable);
+ m_drt->webPage()->settings()->setAttribute(QWebSettings::XSSAuditorEnabled, enable);
+}
+
bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(const QString& animationName,
double time,
const QString& elementId)
@@ -363,3 +421,26 @@ void LayoutTestController::overridePreference(const QString& name, const QVarian
else if (name == "WebKitUsesPageCachePreferenceKey")
QWebSettings::setMaximumPagesInCache(value.toInt());
}
+
+void LayoutTestController::setUserStyleSheetLocation(const QString& url)
+{
+ m_userStyleSheetLocation = QUrl(url);
+}
+
+void LayoutTestController::setUserStyleSheetEnabled(bool enabled)
+{
+ if (enabled)
+ m_drt->webPage()->settings()->setUserStyleSheetUrl(m_userStyleSheetLocation);
+ else
+ m_drt->webPage()->settings()->setUserStyleSheetUrl(QUrl());
+}
+
+void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(bool forbidden, const QString& scheme)
+{
+ qt_drt_setDomainRelaxationForbiddenForURLScheme(forbidden, scheme);
+}
+
+int LayoutTestController::workerThreadCount()
+{
+ return qt_drt_workerThreadCount();
+}
diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
index ac8681f..64b3a15 100644
--- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
+++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
@@ -51,12 +51,11 @@ namespace WebCore {
}
class LayoutTestController : public QObject {
Q_OBJECT
+ Q_PROPERTY(int webHistoryItemCount READ webHistoryItemCount)
+ Q_PROPERTY(int workerThreadCount READ workerThreadCount)
public:
LayoutTestController(WebCore::DumpRenderTree* drt);
- bool isLoading() const { return m_isLoading; }
- void setLoading(bool loading) { m_isLoading = loading; }
-
bool shouldDumpAsText() const { return m_textDump; }
bool shouldDumpBackForwardList() const { return m_dumpBackForwardList; }
bool shouldDumpChildrenAsText() const { return m_dumpChildrenAsText; }
@@ -76,6 +75,9 @@ protected:
signals:
void done();
+ void showPage();
+ void hidePage();
+
public slots:
void maybeDump(bool ok);
void dumpAsText() { m_textDump = true; }
@@ -85,6 +87,7 @@ public slots:
void setCanOpenWindows() { m_canOpenWindows = true; }
void waitUntilDone();
QString counterValueForElementById(const QString& id);
+ int webHistoryItemCount();
void keepWebHistory();
void notifyDone();
void dumpBackForwardList() { m_dumpBackForwardList = true; }
@@ -100,7 +103,7 @@ public slots:
void provisionalLoad();
void setCloseRemainingWindowsWhenComplete(bool = false) {}
int windowCount();
- void display() {}
+ void display();
void clearBackForwardList();
QString pathToLocalResource(const QString& url);
void dumpTitleChanges() { m_dumpTitleChanges = true; }
@@ -115,6 +118,10 @@ public slots:
void setPrivateBrowsingEnabled(bool enable);
void setPopupBlockingEnabled(bool enable);
void setPOSIXLocale(const QString& locale);
+ void resetLoadFinished() { m_loadFinished = false; }
+ void setWindowIsKey(bool isKey);
+ void setMainFrameIsFirstResponder(bool isFirst);
+ void setXSSAuditorEnabled(bool enable);
bool pauseAnimationAtTimeOnElementWithId(const QString& animationName, double time, const QString& elementId);
bool pauseTransitionAtTimeOnElementWithId(const QString& propertyName, double time, const QString& elementId);
@@ -132,12 +139,16 @@ public slots:
void waitForPolicyDelegate();
void overridePreference(const QString& name, const QVariant& value);
+ void setUserStyleSheetLocation(const QString& url);
+ void setUserStyleSheetEnabled(bool enabled);
+ void setDomainRelaxationForbiddenForURLScheme(bool forbidden, const QString& scheme);
+ int workerThreadCount();
private slots:
void processWork();
private:
- bool m_isLoading;
+ bool m_hasDumped;
bool m_textDump;
bool m_dumpBackForwardList;
bool m_dumpChildrenAsText;
@@ -148,10 +159,13 @@ private:
bool m_dumpStatusCallbacks;
bool m_waitForPolicy;
bool m_handleErrorPages;
+ bool m_loadFinished;
+ QUrl m_userStyleSheetLocation;
QBasicTimer m_timeoutTimer;
QWebFrame* m_topLoadingFrame;
WebCore::DumpRenderTree* m_drt;
+ QWebHistory* m_webHistory;
};
#endif // LayoutTestControllerQt_h
diff --git a/WebKitTools/DumpRenderTree/qt/WorkQueueItemQt.cpp b/WebKitTools/DumpRenderTree/qt/WorkQueueItemQt.cpp
index 807a6a4..067e6aa 100644
--- a/WebKitTools/DumpRenderTree/qt/WorkQueueItemQt.cpp
+++ b/WebKitTools/DumpRenderTree/qt/WorkQueueItemQt.cpp
@@ -27,7 +27,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
-#include "WorkQueueItem.h"
+#include "WorkQueueItemQt.h"
QWebFrame* findFrameNamed(const QString& frameName, QWebFrame* frame)
{
diff --git a/WebKitTools/DumpRenderTree/qt/WorkQueueItem.h b/WebKitTools/DumpRenderTree/qt/WorkQueueItemQt.h
index d534493..94da5e1 100644
--- a/WebKitTools/DumpRenderTree/qt/WorkQueueItem.h
+++ b/WebKitTools/DumpRenderTree/qt/WorkQueueItemQt.h
@@ -7,13 +7,13 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
+ * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -27,8 +27,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WorkQueueItem_h
-#define WorkQueueItem_h
+#ifndef WorkQueueItemQt_h
+#define WorkQueueItemQt_h
#include <QPointer>
#include <QString>
@@ -140,4 +140,4 @@ public:
}
};
-#endif // !defined(WorkQueueItem_h)
+#endif // !defined(WorkQueueItemQt_h)
diff --git a/WebKitTools/DumpRenderTree/qt/main.cpp b/WebKitTools/DumpRenderTree/qt/main.cpp
index 719315f..69d3c23 100644
--- a/WebKitTools/DumpRenderTree/qt/main.cpp
+++ b/WebKitTools/DumpRenderTree/qt/main.cpp
@@ -27,7 +27,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "DumpRenderTree.h"
+#include "DumpRenderTreeQt.h"
#include <wtf/AlwaysInline.h>
@@ -40,6 +40,7 @@
#include <qwebsettings.h>
#include <qwebdatabase.h>
#include <qdesktopservices.h>
+#include <qtimer.h>
#include <qwindowsstyle.h>
#ifdef Q_WS_X11
@@ -89,12 +90,14 @@ QString get_backtrace() {
return s;
}
+#ifndef Q_OS_WIN
static NO_RETURN void crashHandler(int sig)
{
fprintf(stderr, "%s\n", strsignal(sig));
fprintf(stderr, "%s\n", get_backtrace().toLatin1().constData());
exit(128 + sig);
}
+#endif
int main(int argc, char* argv[])
{
@@ -121,6 +124,7 @@ int main(int argc, char* argv[])
QX11Info::setAppDpiX(0, 96);
#endif
+#ifndef Q_OS_WIN
signal(SIGILL, crashHandler); /* 4: illegal instruction (not reset when caught) */
signal(SIGTRAP, crashHandler); /* 5: trace trap (not reset when caught) */
signal(SIGFPE, crashHandler); /* 8: floating point exception */
@@ -130,41 +134,42 @@ int main(int argc, char* argv[])
signal(SIGPIPE, crashHandler); /* 13: write on a pipe with no reader */
signal(SIGXCPU, crashHandler); /* 24: exceeded CPU time limit */
signal(SIGXFSZ, crashHandler); /* 25: exceeded file size limit */
+#endif
QStringList args = app.arguments();
if (args.count() < 2) {
- qDebug() << "Usage: DumpRenderTree [-v] filename";
+ qDebug() << "Usage: DumpRenderTree [-v|--pixel-tests] filename";
exit(0);
}
- // supress debug output from Qt if not started with -v
+ // Suppress debug output from Qt if not started with -v
if (!args.contains(QLatin1String("-v")))
qInstallMsgHandler(messageHandler);
WebCore::DumpRenderTree dumper;
- if (args.contains("--pixel-tests"))
+ if (args.contains(QLatin1String("--pixel-tests")))
dumper.setDumpPixels(true);
QString dbDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + QDir::separator() + "qtwebkitdrt";
QWebSettings::setOfflineStoragePath(dbDir);
QWebDatabase::removeAllDatabases();
- if (args.last() == QLatin1String("-")) {
- dumper.open();
+ if (args.contains(QLatin1String("-"))) {
+ QObject::connect(&dumper, SIGNAL(ready()), &dumper, SLOT(readLine()), Qt::QueuedConnection);
+ QTimer::singleShot(0, &dumper, SLOT(readLine()));
} else {
- if (!args.last().startsWith("/")
- && !args.last().startsWith("file:")
- && !args.last().startsWith("http:")
- && !args.last().startsWith("https:")) {
- QString path = QDir::currentPath();
- if (!path.endsWith('/'))
- path.append('/');
- args.last().prepend(path);
+ dumper.setSingleFileMode(true);
+ for (int i = 1; i < args.size(); ++i) {
+ if (!args.at(i).startsWith('-')) {
+ dumper.processLine(args.at(i));
+ break;
+ }
}
- dumper.open(QUrl(args.last()));
}
+
return app.exec();
+
#ifdef Q_WS_X11
FcConfigSetCurrent(0);
#endif