mirror of https://github.com/vitalif/phantomjs
Define the new page callback for interrupting a long-running JavaScript
Issues: https://github.com/ariya/phantomjs/issues/11198 https://github.com/ariya/phantomjs/issues/11183 https://github.com/ariya/phantomjs/issues/111891.x
parent
6a01a8dece
commit
efcc6c7861
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
function forever() {
|
||||
while(true) {}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="forever();">
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -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 () {
|
||||
|
|
Loading…
Reference in New Issue