diff options
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage.cpp | 18 | ||||
-rw-r--r-- | tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp | 17 | ||||
-rw-r--r-- | tests/auto/widgets/util.h | 14 |
3 files changed, 43 insertions, 6 deletions
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 1a3cf5dde..d05a43d0d 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -58,6 +58,15 @@ QWebEnginePagePrivate::QWebEnginePagePrivate() QWebEnginePagePrivate::~QWebEnginePagePrivate() { + // "Cancel" pending callbacks by calling them with an invalid value. + // This guarantees that each callback is called exactly once. + Q_FOREACH (QExplicitlySharedDataPointer<VariantCallback> callback, m_variantCallbacks) + (*callback)(QVariant()); + m_variantCallbacks.clear(); + Q_FOREACH (QExplicitlySharedDataPointer<StringCallback> callback, m_stringCallbacks) + (*callback)(QString()); + m_stringCallbacks.clear(); + delete history; } @@ -148,17 +157,20 @@ void QWebEnginePagePrivate::close() void QWebEnginePagePrivate::didRunJavaScript(const QVariant& result, quint64 requestId) { - (*m_variantCallbacks.take(requestId))(result); + if (QExplicitlySharedDataPointer<VariantCallback> callback = m_variantCallbacks.take(requestId)) + (*callback)(result); } void QWebEnginePagePrivate::didFetchDocumentMarkup(const QString& result, quint64 requestId) { - (*m_stringCallbacks.take(requestId))(result); + if (QExplicitlySharedDataPointer<StringCallback> callback = m_stringCallbacks.take(requestId)) + (*callback)(result); } void QWebEnginePagePrivate::didFetchDocumentInnerText(const QString& result, quint64 requestId) { - (*m_stringCallbacks.take(requestId))(result); + if (QExplicitlySharedDataPointer<StringCallback> callback = m_stringCallbacks.take(requestId)) + (*callback)(result); } void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const diff --git a/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp b/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp index dd78a4076..99ad21152 100644 --- a/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp +++ b/tests/auto/widgets/qwebengineframe/tst_qwebengineframe.cpp @@ -58,6 +58,7 @@ private Q_SLOTS: void javaScriptWindowObjectCleared_data(); void javaScriptWindowObjectCleared(); void javaScriptWindowObjectClearedOnEvaluate(); + void asyncAndDelete(); void earlyToHtml(); void setHtml(); void setHtmlWithImageResource(); @@ -400,6 +401,22 @@ void tst_QWebEngineFrame::javaScriptWindowObjectClearedOnEvaluate() #endif } +void tst_QWebEngineFrame::asyncAndDelete() +{ + QWebEnginePage *page = new QWebEnginePage; + CallbackSpy<QString> plainTextSpy; + CallbackSpy<QString> htmlSpy; + page->toPlainText(ref(plainTextSpy)); + page->toHtml(ref(htmlSpy)); + + delete page; + // Pending callbacks should be called with an empty value in the page's destructor. + QCOMPARE(plainTextSpy.waitForResult(), QString()); + QVERIFY(plainTextSpy.wasCalled()); + QCOMPARE(htmlSpy.waitForResult(), QString()); + QVERIFY(htmlSpy.wasCalled()); +} + void tst_QWebEngineFrame::earlyToHtml() { QString html("<html><head></head><body></body></html>"); diff --git a/tests/auto/widgets/util.h b/tests/auto/widgets/util.h index e5e991f89..a9a3d487c 100644 --- a/tests/auto/widgets/util.h +++ b/tests/auto/widgets/util.h @@ -93,24 +93,32 @@ public: // Tells tr1::ref the result of void operator()(const T &result) when decltype isn't available. typedef void result_type; - CallbackSpy() { + CallbackSpy() : called(false) { timeoutTimer.setSingleShot(true); QObject::connect(&timeoutTimer, SIGNAL(timeout()), &eventLoop, SLOT(quit())); } T waitForResult() { - timeoutTimer.start(10000); - eventLoop.exec(); + if (!called) { + timeoutTimer.start(10000); + eventLoop.exec(); + } return result; } + bool wasCalled() const { + return called; + } + void operator()(const T &result) { this->result = result; + called = true; eventLoop.quit(); } private: Q_DISABLE_COPY(CallbackSpy) + bool called; QTimer timeoutTimer; QEventLoop eventLoop; T result; |