2 * Copyright (C) 2006 Trolltech ASA
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <jsobjects.h>
30 #include <qwebframe.h>
32 #include <qapplication.h>
35 #include "DumpRenderTree.h"
36 extern void qt_dump_editing_callbacks(bool b);
38 class HackWebFrame : public QWebFrame
41 void mousePressEvent(QMouseEvent *e) {
42 QWebFrame::mousePressEvent(e);
44 void mouseReleaseEvent(QMouseEvent *e) {
45 QWebFrame::mouseReleaseEvent(e);
47 void mouseMoveEvent(QMouseEvent *e) {
48 QWebFrame::mouseMoveEvent(e);
52 HackWebFrame(QWebPage *parent, QWebFrameData *frameData) : QWebFrame(parent, frameData) {}
53 HackWebFrame(QWebFrame *parent, QWebFrameData *frameData) : QWebFrame(parent, frameData) {}
57 LayoutTestController::LayoutTestController(WebCore::DumpRenderTree *drt)
65 void LayoutTestController::reset()
69 m_dumpChildrenAsText = false;
70 m_canOpenWindows = false;
71 m_waitForDone = false;
72 m_dumpTitleChanges = false;
74 killTimer(m_timeoutTimer);
77 m_topLoadingFrame = 0;
78 qt_dump_editing_callbacks(false);
81 void LayoutTestController::maybeDump(bool ok)
83 QWebFrame *frame = qobject_cast<QWebFrame*>(sender());
84 if (frame != m_topLoadingFrame)
87 m_topLoadingFrame = 0;
89 if (!shouldWaitUntilDone()) {
95 void LayoutTestController::waitUntilDone()
97 //qDebug() << ">>>>waitForDone";
99 m_timeoutTimer = startTimer(5000);
102 void LayoutTestController::notifyDone()
104 //qDebug() << ">>>>notifyDone";
107 killTimer(m_timeoutTimer);
113 int LayoutTestController::windowCount()
115 return m_drt->windowCount();
118 void LayoutTestController::clearBackForwardList()
120 m_drt->webPage()->history().clear();
124 void LayoutTestController::dumpEditingCallbacks()
126 qDebug() << ">>>dumpEditingCallbacks";
127 qt_dump_editing_callbacks(true);
130 void LayoutTestController::queueReload()
132 //qDebug() << ">>>queueReload";
135 void LayoutTestController::provisionalLoad()
137 QWebFrame *frame = qobject_cast<QWebFrame*>(sender());
138 if (!m_topLoadingFrame && m_isLoading)
139 m_topLoadingFrame = frame;
142 void LayoutTestController::timerEvent(QTimerEvent *)
144 qDebug() << ">>>>>>>>>>>>> timeout";
148 QString LayoutTestController::encodeHostName(const QString &host)
150 QString encoded = QString::fromLatin1(QUrl::toAce(host + QLatin1String(".no")));
151 encoded.truncate(encoded.length() - 3); // strip .no
155 QString LayoutTestController::decodeHostName(const QString &host)
157 QString decoded = QUrl::fromAce(host.toLatin1() + QByteArray(".no"));
158 decoded.truncate(decoded.length() - 3);
163 EventSender::EventSender(QWebPage *parent)
169 void EventSender::mouseDown()
171 QWebFrame *frame = frameUnderMouse();
172 // qDebug() << "EventSender::mouseDown" << frame;
175 QMouseEvent event(QEvent::MouseButtonPress, m_mousePos - frame->pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
176 static_cast<HackWebFrame *>(frame)->mousePressEvent(&event);
179 void EventSender::mouseUp()
181 QWebFrame *frame = frameUnderMouse();
182 // qDebug() << "EventSender::mouseUp" << frame;
185 QMouseEvent event(QEvent::MouseButtonRelease, m_mousePos - frame->pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
186 static_cast<HackWebFrame *>(frame)->mouseReleaseEvent(&event);
189 void EventSender::mouseMoveTo(int x, int y)
191 QWebFrame *frame = frameUnderMouse();
192 // qDebug() << "EventSender::mouseMoveTo" << x << y;
193 m_mousePos = QPoint(x, y);
194 QMouseEvent event(QEvent::MouseMove, m_mousePos - frame->pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
195 static_cast<HackWebFrame *>(frame)->mouseMoveEvent(&event);
198 void EventSender::leapForward(int ms)
201 qDebug() << "EventSender::leapForward" << ms;
204 void EventSender::keyDown(const QString &string, const QStringList &modifiers)
207 Qt::KeyboardModifiers modifs = 0;
208 for (int i = 0; i < modifiers.size(); ++i) {
209 const QString &m = modifiers.at(i);
211 modifs |= Qt::ControlModifier;
212 else if (m == "shiftKey")
213 modifs |= Qt::ShiftModifier;
214 else if (m == "altKey")
215 modifs |= Qt::AltModifier;
216 else if (m == "metaKey")
217 modifs |= Qt::MetaModifier;
220 if (string.length() == 1) {
221 code = string.unicode()->unicode();
222 qDebug() << ">>>>>>>>> keyDown" << code << (char)code;
223 // map special keycodes used by the tests to something that works for Qt/X11
226 if (modifs == Qt::ShiftModifier)
227 code = Qt::Key_Backtab;
229 } else if (code == 127) {
230 code = Qt::Key_Backspace;
231 if (modifs == Qt::AltModifier)
232 modifs = Qt::ControlModifier;
234 } else if (code == 'o' && modifs == Qt::ControlModifier) {
235 s = QLatin1String("\n");
238 } else if (code == 'y' && modifs == Qt::ControlModifier) {
239 s = QLatin1String("c");
241 } else if (code == 'k' && modifs == Qt::ControlModifier) {
242 s = QLatin1String("x");
244 } else if (code == 'a' && modifs == Qt::ControlModifier) {
248 } else if (code == 0xf702) {
251 if (modifs & Qt::MetaModifier) {
253 modifs &= ~Qt::MetaModifier;
255 } else if (code == 0xf703) {
257 code = Qt::Key_Right;
258 if (modifs & Qt::MetaModifier) {
260 modifs &= ~Qt::MetaModifier;
262 } else if (code == 'a' && modifs == Qt::ControlModifier) {
267 code = string.unicode()->toUpper().unicode();
270 QKeyEvent event(QEvent::KeyPress, code, modifs, s);
271 QApplication::sendEvent(m_page, &event);
274 QWebFrame *EventSender::frameUnderMouse() const
276 QWebFrame *frame = m_page->mainFrame();
279 QList<QWebFrame*> children = frame->childFrames();
280 for (int i = 0; i < children.size(); ++i) {
281 if (children.at(i)->geometry().contains(m_mousePos)) {
282 frame = children.at(i);
286 if (frame->geometry().contains(m_mousePos))
292 TextInputController::TextInputController(QWebPage *parent)
297 void TextInputController::doCommand(const QString &command)
299 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
301 if (command == "moveBackwardAndModifySelection:") {
302 modifiers |= Qt::ShiftModifier;
303 keycode = Qt::Key_Left;
304 } else if(command =="moveDown:") {
305 keycode = Qt::Key_Down;
306 } else if(command =="moveDownAndModifySelection:") {
307 modifiers |= Qt::ShiftModifier;
308 keycode = Qt::Key_Down;
309 } else if(command =="moveForward:") {
310 keycode = Qt::Key_Right;
311 } else if(command =="moveForwardAndModifySelection:") {
312 modifiers |= Qt::ShiftModifier;
313 keycode = Qt::Key_Right;
314 } else if(command =="moveLeft:") {
315 keycode = Qt::Key_Left;
316 } else if(command =="moveLeftAndModifySelection:") {
317 modifiers |= Qt::ShiftModifier;
318 keycode = Qt::Key_Left;
319 } else if(command =="moveRight:") {
320 keycode = Qt::Key_Right;
321 } else if(command =="moveRightAndModifySelection:") {
322 modifiers |= Qt::ShiftModifier;
323 keycode = Qt::Key_Right;
324 } else if(command =="moveToBeginningOfDocument:") {
325 modifiers |= Qt::ControlModifier;
326 keycode = Qt::Key_Home;
327 } else if(command =="moveToBeginningOfLine:") {
328 keycode = Qt::Key_Home;
329 // } else if(command =="moveToBeginningOfParagraph:") {
330 } else if(command =="moveToEndOfDocument:") {
331 modifiers |= Qt::ControlModifier;
332 keycode = Qt::Key_End;
333 } else if(command =="moveToEndOfLine:") {
334 keycode = Qt::Key_End;
335 // } else if(command =="moveToEndOfParagraph:") {
336 } else if(command =="moveUp:") {
337 keycode = Qt::Key_Up;
338 } else if(command =="moveUpAndModifySelection:") {
339 modifiers |= Qt::ShiftModifier;
340 keycode = Qt::Key_Up;
341 } else if(command =="moveWordBackward:") {
342 modifiers |= Qt::ControlModifier;
343 keycode = Qt::Key_Up;
344 } else if(command =="moveWordBackwardAndModifySelection:") {
345 modifiers |= Qt::ShiftModifier;
346 modifiers |= Qt::ControlModifier;
347 keycode = Qt::Key_Left;
348 } else if(command =="moveWordForward:") {
349 modifiers |= Qt::ControlModifier;
350 keycode = Qt::Key_Right;
351 } else if(command =="moveWordForwardAndModifySelection:") {
352 modifiers |= Qt::ControlModifier;
353 modifiers |= Qt::ShiftModifier;
354 keycode = Qt::Key_Right;
355 } else if(command =="moveWordLeft:") {
356 modifiers |= Qt::ControlModifier;
357 keycode = Qt::Key_Left;
358 } else if(command =="moveWordRight:") {
359 modifiers |= Qt::ControlModifier;
360 keycode = Qt::Key_Left;
361 } else if(command =="moveWordRightAndModifySelection:") {
362 modifiers |= Qt::ShiftModifier;
363 modifiers |= Qt::ControlModifier;
364 keycode = Qt::Key_Right;
365 } else if(command =="moveWordLeftAndModifySelection:") {
366 modifiers |= Qt::ShiftModifier;
367 modifiers |= Qt::ControlModifier;
368 keycode = Qt::Key_Left;
369 } else if(command =="pageDown:") {
370 keycode = Qt::Key_PageDown;
371 } else if(command =="pageUp:") {
372 keycode = Qt::Key_PageUp;
373 } else if(command == "deleteWordBackward:") {
374 modifiers |= Qt::ControlModifier;
375 keycode = Qt::Key_Backspace;
376 } else if(command == "deleteBackward:") {
377 keycode = Qt::Key_Backspace;
378 } else if(command == "deleteForward:") {
379 keycode = Qt::Key_Delete;
381 QKeyEvent event(QEvent::KeyPress, keycode, modifiers);
382 QApplication::sendEvent(parent(), &event);
383 QKeyEvent event2(QEvent::KeyRelease, keycode, modifiers);
384 QApplication::sendEvent(parent(), &event2);