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
|
// @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,
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
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 () {
|
||||||
|
|
Loading…
Reference in New Issue