2011-02-26 03:57:55 +00:00
|
|
|
#include "JavascriptInvocation.h"
|
2012-12-11 03:53:03 +00:00
|
|
|
#include "WebPage.h"
|
2013-01-20 23:57:04 +00:00
|
|
|
#include "InvocationResult.h"
|
2012-12-11 03:53:03 +00:00
|
|
|
#include <QApplication>
|
2013-02-25 09:28:43 +00:00
|
|
|
#include <QEvent>
|
2013-02-27 21:25:01 +00:00
|
|
|
#include <QContextMenuEvent>
|
2011-02-26 03:57:55 +00:00
|
|
|
|
2012-12-11 03:53:03 +00:00
|
|
|
JavascriptInvocation::JavascriptInvocation(const QString &functionName, const QStringList &arguments, WebPage *page, QObject *parent) : QObject(parent) {
|
2011-02-26 03:57:55 +00:00
|
|
|
m_functionName = functionName;
|
|
|
|
m_arguments = arguments;
|
2012-12-11 03:53:03 +00:00
|
|
|
m_page = page;
|
2011-02-26 03:57:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QString &JavascriptInvocation::functionName() {
|
|
|
|
return m_functionName;
|
|
|
|
}
|
|
|
|
|
|
|
|
QStringList &JavascriptInvocation::arguments() {
|
|
|
|
return m_arguments;
|
|
|
|
}
|
2012-12-11 03:53:03 +00:00
|
|
|
|
2013-02-02 22:32:54 +00:00
|
|
|
QVariant JavascriptInvocation::getError() {
|
2013-01-20 23:57:04 +00:00
|
|
|
return m_error;
|
|
|
|
}
|
|
|
|
|
2013-02-02 22:32:54 +00:00
|
|
|
void JavascriptInvocation::setError(QVariant error) {
|
2013-01-20 23:57:04 +00:00
|
|
|
m_error = error;
|
|
|
|
}
|
|
|
|
|
|
|
|
InvocationResult JavascriptInvocation::invoke(QWebFrame *frame) {
|
|
|
|
frame->addToJavaScriptWindowObject("CapybaraInvocation", this);
|
|
|
|
QVariant result = frame->evaluateJavaScript("Capybara.invoke()");
|
2013-02-02 22:32:54 +00:00
|
|
|
if (getError().isValid())
|
2013-01-20 23:57:04 +00:00
|
|
|
return InvocationResult(getError(), true);
|
2013-02-02 22:32:54 +00:00
|
|
|
else
|
|
|
|
return InvocationResult(result);
|
2013-01-20 23:57:04 +00:00
|
|
|
}
|
|
|
|
|
2013-02-25 09:28:43 +00:00
|
|
|
void JavascriptInvocation::leftClick(int x, int y) {
|
2013-01-21 00:13:58 +00:00
|
|
|
QPoint mousePos(x, y);
|
|
|
|
|
2013-02-26 19:32:03 +00:00
|
|
|
hover(mousePos);
|
2013-02-25 09:28:43 +00:00
|
|
|
JavascriptInvocation::mouseEvent(QEvent::MouseButtonPress, mousePos, Qt::LeftButton);
|
|
|
|
JavascriptInvocation::mouseEvent(QEvent::MouseButtonRelease, mousePos, Qt::LeftButton);
|
|
|
|
}
|
|
|
|
|
|
|
|
void JavascriptInvocation::rightClick(int x, int y) {
|
|
|
|
QPoint mousePos(x, y);
|
|
|
|
|
2013-02-26 19:32:03 +00:00
|
|
|
hover(mousePos);
|
2013-02-25 09:28:43 +00:00
|
|
|
JavascriptInvocation::mouseEvent(QEvent::MouseButtonPress, mousePos, Qt::RightButton);
|
2013-02-27 21:25:01 +00:00
|
|
|
|
|
|
|
// swallowContextMenuEvent tries to fire contextmenu event in html page
|
|
|
|
QContextMenuEvent *event = new QContextMenuEvent(QContextMenuEvent::Mouse, mousePos);
|
|
|
|
m_page->swallowContextMenuEvent(event);
|
|
|
|
|
|
|
|
JavascriptInvocation::mouseEvent(QEvent::MouseButtonRelease, mousePos, Qt::RightButton);
|
2013-02-25 09:28:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JavascriptInvocation::doubleClick(int x, int y) {
|
|
|
|
QPoint mousePos(x, y);
|
2013-01-21 00:13:58 +00:00
|
|
|
|
2013-02-25 09:28:43 +00:00
|
|
|
JavascriptInvocation::mouseEvent(QEvent::MouseButtonDblClick, mousePos, Qt::LeftButton);
|
|
|
|
JavascriptInvocation::mouseEvent(QEvent::MouseButtonRelease, mousePos, Qt::LeftButton);
|
|
|
|
}
|
2013-01-21 00:13:58 +00:00
|
|
|
|
2013-02-25 09:28:43 +00:00
|
|
|
void JavascriptInvocation::mouseEvent(QEvent::Type type, const QPoint &position, Qt::MouseButton button) {
|
|
|
|
QMouseEvent event(type, position, button, button, Qt::NoModifier);
|
2013-01-21 00:13:58 +00:00
|
|
|
QApplication::sendEvent(m_page, &event);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool JavascriptInvocation::clickTest(QWebElement element, int absoluteX, int absoluteY) {
|
|
|
|
QPoint mousePos(absoluteX, absoluteY);
|
|
|
|
QWebHitTestResult res = m_page->mainFrame()->hitTestContent(mousePos);
|
|
|
|
return res.frame() == element.webFrame();
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariantMap JavascriptInvocation::clickPosition(QWebElement element, int left, int top, int width, int height) {
|
2012-12-11 03:53:03 +00:00
|
|
|
QRect elementBox(left, top, width, height);
|
2013-01-13 14:13:57 +00:00
|
|
|
QRect viewport(QPoint(0, 0), m_page->viewportSize());
|
|
|
|
QRect boundedBox = elementBox.intersected(viewport);
|
|
|
|
QPoint mousePos = boundedBox.center();
|
|
|
|
|
2013-01-21 00:13:58 +00:00
|
|
|
QVariantMap m;
|
|
|
|
m["relativeX"] = mousePos.x();
|
|
|
|
m["relativeY"] = mousePos.y();
|
2013-01-13 14:13:57 +00:00
|
|
|
|
2012-12-11 03:53:03 +00:00
|
|
|
QWebFrame *parent = element.webFrame();
|
|
|
|
while (parent) {
|
2013-01-12 23:02:10 +00:00
|
|
|
elementBox.translate(parent->geometry().topLeft());
|
2012-12-11 03:53:03 +00:00
|
|
|
parent = parent->parentFrame();
|
|
|
|
}
|
|
|
|
|
2013-01-13 14:13:57 +00:00
|
|
|
boundedBox = elementBox.intersected(viewport);
|
|
|
|
mousePos = boundedBox.center();
|
|
|
|
|
2013-01-21 00:13:58 +00:00
|
|
|
m["absoluteX"] = mousePos.x();
|
|
|
|
m["absoluteY"] = mousePos.y();
|
2013-01-12 23:02:10 +00:00
|
|
|
|
2013-01-21 00:13:58 +00:00
|
|
|
return m;
|
2012-12-11 03:53:03 +00:00
|
|
|
}
|
2013-02-26 19:32:03 +00:00
|
|
|
|
|
|
|
void JavascriptInvocation::hover(int absoluteX, int absoluteY) {
|
|
|
|
QPoint mousePos(absoluteX, absoluteY);
|
|
|
|
hover(mousePos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void JavascriptInvocation::hover(const QPoint &mousePos) {
|
|
|
|
mouseEvent(QEvent::MouseMove, mousePos, Qt::NoButton);
|
|
|
|
}
|
2013-03-21 03:20:14 +00:00
|
|
|
|
|
|
|
int JavascriptInvocation::keyCodeFor(const QChar &key) {
|
|
|
|
switch(key.unicode()) {
|
|
|
|
case 0x18:
|
|
|
|
return Qt::Key_Cancel;
|
|
|
|
case 0x08:
|
|
|
|
return Qt::Key_Backspace;
|
|
|
|
case 0x09:
|
|
|
|
return Qt::Key_Tab;
|
|
|
|
case 0x0A:
|
|
|
|
return Qt::Key_Return;
|
|
|
|
case 0x1B:
|
|
|
|
return Qt::Key_Escape;
|
|
|
|
case 0x7F:
|
|
|
|
return Qt::Key_Delete;
|
|
|
|
default:
|
|
|
|
int keyCode = key.toUpper().toLatin1();
|
|
|
|
if (keyCode >= Qt::Key_Space || keyCode <= Qt::Key_AsciiTilde)
|
|
|
|
return keyCode;
|
|
|
|
else
|
|
|
|
return Qt::Key_unknown;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void JavascriptInvocation::keypress(QChar key) {
|
|
|
|
int keyCode = keyCodeFor(key);
|
|
|
|
QKeyEvent event(QKeyEvent::KeyPress, keyCode, Qt::NoModifier, key);
|
|
|
|
QApplication::sendEvent(m_page, &event);
|
|
|
|
event = QKeyEvent(QKeyEvent::KeyRelease, keyCode, Qt::NoModifier, key);
|
|
|
|
QApplication::sendEvent(m_page, &event);
|
|
|
|
}
|