Skip to content
This repository was archived by the owner on May 30, 2023. It is now read-only.

Commit efcc6c7

Browse files
vitalliumariya
authored andcommitted
Define the new page callback for interrupting a long-running JavaScript
Issues: #11198 #11183 #11189
1 parent 6a01a8d commit efcc6c7

File tree

5 files changed

+77
-1
lines changed

5 files changed

+77
-1
lines changed

src/modules/webpage.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,9 @@ function decorateNewPage(opts, page) {
468468
// @see https://developer.mozilla.org/en/DOM/window.prompt
469469
definePageCallbackHandler(page, handlers, "onPrompt", "_getJsPromptCallback");
470470

471+
// Calls from within the page when some javascript code running to long
472+
definePageCallbackHandler(page, handlers, "onLongRunningScript", "_getJsInterruptCallback");
473+
471474
page.event = {};
472475
page.event.modifier = {
473476
shift: 0x02000000,

src/webpage.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,14 @@ class CustomPage: public QWebPage
112112

113113
public slots:
114114
bool shouldInterruptJavaScript() {
115-
QApplication::processEvents(QEventLoop::AllEvents, 42);
115+
m_webPage->javascriptInterrupt();
116+
117+
if (m_webPage->m_shouldInterruptJs) {
118+
119+
// reset our flag
120+
m_webPage->m_shouldInterruptJs = false;
121+
return true;
122+
}
116123
return false;
117124
}
118125

@@ -251,6 +258,7 @@ class WebpageCallbacks : public QObject
251258
, m_filePickerCallback(NULL)
252259
, m_jsConfirmCallback(NULL)
253260
, m_jsPromptCallback(NULL)
261+
, m_jsInterruptCallback(NULL)
254262
{
255263
}
256264

@@ -289,6 +297,15 @@ class WebpageCallbacks : public QObject
289297
}
290298
return m_jsPromptCallback;
291299
}
300+
301+
QObject *getJsInterruptCallback() {
302+
qDebug() << "WebpageCallbacks - getJsInterruptCallback";
303+
304+
if (!m_jsInterruptCallback) {
305+
m_jsInterruptCallback = new Callback(this);
306+
}
307+
return m_jsInterruptCallback;
308+
}
292309

293310
public slots:
294311
QVariant call(const QVariantList &arguments) {
@@ -303,6 +320,7 @@ public slots:
303320
Callback *m_filePickerCallback;
304321
Callback *m_jsConfirmCallback;
305322
Callback *m_jsPromptCallback;
323+
Callback *m_jsInterruptCallback;
306324

307325
friend class WebPage;
308326
};
@@ -314,6 +332,7 @@ WebPage::WebPage(QObject *parent, const QUrl &baseUrl)
314332
, m_mousePos(QPoint(0, 0))
315333
, m_ownsPages(true)
316334
, m_loadingProgress(0)
335+
, m_shouldInterruptJs(false)
317336
{
318337
setObjectName("WebPage");
319338
m_callbacks = new WebpageCallbacks(this);
@@ -729,6 +748,17 @@ bool WebPage::javaScriptPrompt(const QString &msg, const QString &defaultValue,
729748
return false;
730749
}
731750

751+
void WebPage::javascriptInterrupt()
752+
{
753+
if (m_callbacks->m_jsInterruptCallback) {
754+
QVariant res = m_callbacks->m_jsInterruptCallback->call(QVariantList());
755+
756+
if (res.canConvert<bool>()) {
757+
m_shouldInterruptJs = res.toBool();
758+
}
759+
}
760+
}
761+
732762
void WebPage::finish(bool ok)
733763
{
734764
QString status = ok ? "success" : "fail";
@@ -1293,6 +1323,15 @@ QObject *WebPage::_getJsPromptCallback()
12931323
return m_callbacks->getJsPromptCallback();
12941324
}
12951325

1326+
QObject *WebPage::_getJsInterruptCallback()
1327+
{
1328+
if (!m_callbacks) {
1329+
m_callbacks = new WebpageCallbacks(this);
1330+
}
1331+
1332+
return m_callbacks->getJsInterruptCallback();
1333+
}
1334+
12961335
void WebPage::sendEvent(const QString &type, const QVariant &arg1, const QVariant &arg2, const QString &mouseButton, const QVariant &modifierArg)
12971336
{
12981337
Qt::KeyboardModifiers keyboardModifiers(modifierArg.toInt());
@@ -1580,4 +1619,9 @@ void WebPage::updateLoadingProgress(int progress)
15801619
m_loadingProgress = progress;
15811620
}
15821621

1622+
void WebPage::stopJavaScript()
1623+
{
1624+
m_shouldInterruptJs = true;
1625+
}
1626+
15831627
#include "webpage.moc"

src/webpage.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ public slots:
258258
QObject *_getFilePickerCallback();
259259
QObject *_getJsConfirmCallback();
260260
QObject *_getJsPromptCallback();
261+
QObject *_getJsInterruptCallback();
261262
void _uploadFile(const QString &selector, const QStringList &fileNames);
262263
void sendEvent(const QString &type, const QVariant &arg1 = QVariant(), const QVariant &arg2 = QVariant(), const QString &mouseButton = QString(), const QVariant &modifierArg = QVariant());
263264

@@ -459,6 +460,8 @@ public slots:
459460
*/
460461
void stop();
461462

463+
void stopJavaScript();
464+
462465
signals:
463466
void initialized();
464467
void loadStarted();
@@ -497,6 +500,7 @@ private slots:
497500
QString filePicker(const QString &oldFile);
498501
bool javaScriptConfirm(const QString &msg);
499502
bool javaScriptPrompt(const QString &msg, const QString &defaultValue, QString *result);
503+
void javascriptInterrupt();
500504

501505
private:
502506
CustomPage *m_customWebPage;
@@ -513,6 +517,7 @@ private slots:
513517
QPoint m_mousePos;
514518
bool m_ownsPages;
515519
int m_loadingProgress;
520+
bool m_shouldInterruptJs;
516521

517522
friend class Phantom;
518523
friend class CustomPage;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<html>
2+
<head>
3+
<script type="text/javascript">
4+
function forever() {
5+
while(true) {}
6+
}
7+
</script>
8+
</head>
9+
<body onload="forever();">
10+
11+
</body>
12+
</html>

test/webpage-spec.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,18 @@ describe("WebPage object", function() {
13071307
server.close();
13081308
});
13091309
});
1310+
1311+
it("should interrupt a long-running JavaScript code", function() {
1312+
var page = new WebPage();
1313+
1314+
page.onLongRunningScript = function() {
1315+
page.stopJavaScript();
1316+
};
1317+
1318+
page.open('../test/webpage-spec-frames/forever.html', function(status) {
1319+
expect(status).toEqual('success');
1320+
});
1321+
});
13101322
});
13111323

13121324
describe("WebPage construction with options", function () {

0 commit comments

Comments
 (0)