Vitaliy Slobodin 2013-04-03 22:06:38 +04:00 committed by Ariya Hidayat
parent 6a01a8dece
commit efcc6c7861
5 changed files with 77 additions and 1 deletions

View File

@ -468,6 +468,9 @@ function decorateNewPage(opts, page) {
// @see https://developer.mozilla.org/en/DOM/window.prompt // @see https://developer.mozilla.org/en/DOM/window.prompt
definePageCallbackHandler(page, handlers, "onPrompt", "_getJsPromptCallback"); definePageCallbackHandler(page, handlers, "onPrompt", "_getJsPromptCallback");
// Calls from within the page when some javascript code running to long
definePageCallbackHandler(page, handlers, "onLongRunningScript", "_getJsInterruptCallback");
page.event = {}; page.event = {};
page.event.modifier = { page.event.modifier = {
shift: 0x02000000, shift: 0x02000000,

View File

@ -112,7 +112,14 @@ public:
public slots: public slots:
bool shouldInterruptJavaScript() { bool shouldInterruptJavaScript() {
QApplication::processEvents(QEventLoop::AllEvents, 42); m_webPage->javascriptInterrupt();
if (m_webPage->m_shouldInterruptJs) {
// reset our flag
m_webPage->m_shouldInterruptJs = false;
return true;
}
return false; return false;
} }
@ -251,6 +258,7 @@ public:
, m_filePickerCallback(NULL) , m_filePickerCallback(NULL)
, m_jsConfirmCallback(NULL) , m_jsConfirmCallback(NULL)
, m_jsPromptCallback(NULL) , m_jsPromptCallback(NULL)
, m_jsInterruptCallback(NULL)
{ {
} }
@ -290,6 +298,15 @@ public:
return m_jsPromptCallback; return m_jsPromptCallback;
} }
QObject *getJsInterruptCallback() {
qDebug() << "WebpageCallbacks - getJsInterruptCallback";
if (!m_jsInterruptCallback) {
m_jsInterruptCallback = new Callback(this);
}
return m_jsInterruptCallback;
}
public slots: public slots:
QVariant call(const QVariantList &arguments) { QVariant call(const QVariantList &arguments) {
if (m_genericCallback) { if (m_genericCallback) {
@ -303,6 +320,7 @@ private:
Callback *m_filePickerCallback; Callback *m_filePickerCallback;
Callback *m_jsConfirmCallback; Callback *m_jsConfirmCallback;
Callback *m_jsPromptCallback; Callback *m_jsPromptCallback;
Callback *m_jsInterruptCallback;
friend class WebPage; friend class WebPage;
}; };
@ -314,6 +332,7 @@ WebPage::WebPage(QObject *parent, const QUrl &baseUrl)
, m_mousePos(QPoint(0, 0)) , m_mousePos(QPoint(0, 0))
, m_ownsPages(true) , m_ownsPages(true)
, m_loadingProgress(0) , m_loadingProgress(0)
, m_shouldInterruptJs(false)
{ {
setObjectName("WebPage"); setObjectName("WebPage");
m_callbacks = new WebpageCallbacks(this); m_callbacks = new WebpageCallbacks(this);
@ -729,6 +748,17 @@ bool WebPage::javaScriptPrompt(const QString &msg, const QString &defaultValue,
return false; return false;
} }
void WebPage::javascriptInterrupt()
{
if (m_callbacks->m_jsInterruptCallback) {
QVariant res = m_callbacks->m_jsInterruptCallback->call(QVariantList());
if (res.canConvert<bool>()) {
m_shouldInterruptJs = res.toBool();
}
}
}
void WebPage::finish(bool ok) void WebPage::finish(bool ok)
{ {
QString status = ok ? "success" : "fail"; QString status = ok ? "success" : "fail";
@ -1293,6 +1323,15 @@ QObject *WebPage::_getJsPromptCallback()
return m_callbacks->getJsPromptCallback(); return m_callbacks->getJsPromptCallback();
} }
QObject *WebPage::_getJsInterruptCallback()
{
if (!m_callbacks) {
m_callbacks = new WebpageCallbacks(this);
}
return m_callbacks->getJsInterruptCallback();
}
void WebPage::sendEvent(const QString &type, const QVariant &arg1, const QVariant &arg2, const QString &mouseButton, const QVariant &modifierArg) void WebPage::sendEvent(const QString &type, const QVariant &arg1, const QVariant &arg2, const QString &mouseButton, const QVariant &modifierArg)
{ {
Qt::KeyboardModifiers keyboardModifiers(modifierArg.toInt()); Qt::KeyboardModifiers keyboardModifiers(modifierArg.toInt());
@ -1580,4 +1619,9 @@ void WebPage::updateLoadingProgress(int progress)
m_loadingProgress = progress; m_loadingProgress = progress;
} }
void WebPage::stopJavaScript()
{
m_shouldInterruptJs = true;
}
#include "webpage.moc" #include "webpage.moc"

View File

@ -258,6 +258,7 @@ public slots:
QObject *_getFilePickerCallback(); QObject *_getFilePickerCallback();
QObject *_getJsConfirmCallback(); QObject *_getJsConfirmCallback();
QObject *_getJsPromptCallback(); QObject *_getJsPromptCallback();
QObject *_getJsInterruptCallback();
void _uploadFile(const QString &selector, const QStringList &fileNames); void _uploadFile(const QString &selector, const QStringList &fileNames);
void sendEvent(const QString &type, const QVariant &arg1 = QVariant(), const QVariant &arg2 = QVariant(), const QString &mouseButton = QString(), const QVariant &modifierArg = QVariant()); void sendEvent(const QString &type, const QVariant &arg1 = QVariant(), const QVariant &arg2 = QVariant(), const QString &mouseButton = QString(), const QVariant &modifierArg = QVariant());
@ -459,6 +460,8 @@ public slots:
*/ */
void stop(); void stop();
void stopJavaScript();
signals: signals:
void initialized(); void initialized();
void loadStarted(); void loadStarted();
@ -497,6 +500,7 @@ private:
QString filePicker(const QString &oldFile); QString filePicker(const QString &oldFile);
bool javaScriptConfirm(const QString &msg); bool javaScriptConfirm(const QString &msg);
bool javaScriptPrompt(const QString &msg, const QString &defaultValue, QString *result); bool javaScriptPrompt(const QString &msg, const QString &defaultValue, QString *result);
void javascriptInterrupt();
private: private:
CustomPage *m_customWebPage; CustomPage *m_customWebPage;
@ -513,6 +517,7 @@ private:
QPoint m_mousePos; QPoint m_mousePos;
bool m_ownsPages; bool m_ownsPages;
int m_loadingProgress; int m_loadingProgress;
bool m_shouldInterruptJs;
friend class Phantom; friend class Phantom;
friend class CustomPage; friend class CustomPage;

View File

@ -0,0 +1,12 @@
<html>
<head>
<script type="text/javascript">
function forever() {
while(true) {}
}
</script>
</head>
<body onload="forever();">
</body>
</html>

View File

@ -1307,6 +1307,18 @@ describe("WebPage object", function() {
server.close(); server.close();
}); });
}); });
it("should interrupt a long-running JavaScript code", function() {
var page = new WebPage();
page.onLongRunningScript = function() {
page.stopJavaScript();
};
page.open('../test/webpage-spec-frames/forever.html', function(status) {
expect(status).toEqual('success');
});
});
}); });
describe("WebPage construction with options", function () { describe("WebPage construction with options", function () {