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
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.modifier = {
shift: 0x02000000,

View File

@ -112,7 +112,14 @@ public:
public slots:
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;
}
@ -251,6 +258,7 @@ public:
, m_filePickerCallback(NULL)
, m_jsConfirmCallback(NULL)
, m_jsPromptCallback(NULL)
, m_jsInterruptCallback(NULL)
{
}
@ -289,6 +297,15 @@ public:
}
return m_jsPromptCallback;
}
QObject *getJsInterruptCallback() {
qDebug() << "WebpageCallbacks - getJsInterruptCallback";
if (!m_jsInterruptCallback) {
m_jsInterruptCallback = new Callback(this);
}
return m_jsInterruptCallback;
}
public slots:
QVariant call(const QVariantList &arguments) {
@ -303,6 +320,7 @@ private:
Callback *m_filePickerCallback;
Callback *m_jsConfirmCallback;
Callback *m_jsPromptCallback;
Callback *m_jsInterruptCallback;
friend class WebPage;
};
@ -314,6 +332,7 @@ WebPage::WebPage(QObject *parent, const QUrl &baseUrl)
, m_mousePos(QPoint(0, 0))
, m_ownsPages(true)
, m_loadingProgress(0)
, m_shouldInterruptJs(false)
{
setObjectName("WebPage");
m_callbacks = new WebpageCallbacks(this);
@ -729,6 +748,17 @@ bool WebPage::javaScriptPrompt(const QString &msg, const QString &defaultValue,
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)
{
QString status = ok ? "success" : "fail";
@ -1293,6 +1323,15 @@ QObject *WebPage::_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)
{
Qt::KeyboardModifiers keyboardModifiers(modifierArg.toInt());
@ -1580,4 +1619,9 @@ void WebPage::updateLoadingProgress(int progress)
m_loadingProgress = progress;
}
void WebPage::stopJavaScript()
{
m_shouldInterruptJs = true;
}
#include "webpage.moc"

View File

@ -258,6 +258,7 @@ public slots:
QObject *_getFilePickerCallback();
QObject *_getJsConfirmCallback();
QObject *_getJsPromptCallback();
QObject *_getJsInterruptCallback();
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());
@ -459,6 +460,8 @@ public slots:
*/
void stop();
void stopJavaScript();
signals:
void initialized();
void loadStarted();
@ -497,6 +500,7 @@ private:
QString filePicker(const QString &oldFile);
bool javaScriptConfirm(const QString &msg);
bool javaScriptPrompt(const QString &msg, const QString &defaultValue, QString *result);
void javascriptInterrupt();
private:
CustomPage *m_customWebPage;
@ -513,6 +517,7 @@ private:
QPoint m_mousePos;
bool m_ownsPages;
int m_loadingProgress;
bool m_shouldInterruptJs;
friend class Phantom;
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();
});
});
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 () {