Avoid deleting a QWebPage inside its own signal emission.

If Phantom.exit() is called inside the handler for loadFinished(), we
end up in a situation that QWebPage is deleting itself during a signal
emission. This used to be OK in QtWebKit 2.0 (Qt 4.7) but is not OK for
QtWebKit 2.2 (upcoming Qt 4.8).

http://code.google.com/p/phantomjs/issues/detail?id=251

Patch by Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org>.
1.4
Ariya Hidayat 2011-10-05 17:26:46 -07:00
parent 3ba6649706
commit fe20c0987d
2 changed files with 24 additions and 11 deletions

View File

@ -108,10 +108,11 @@ WebPage::WebPage(QObject *parent, const Config *config)
setObjectName("WebPage"); setObjectName("WebPage");
m_webPage = new CustomPage(this); m_webPage = new CustomPage(this);
m_mainFrame = m_webPage->mainFrame(); m_mainFrame = m_webPage->mainFrame();
m_mainFrame->setHtml(BLANK_HTML);
connect(m_mainFrame, SIGNAL(javaScriptWindowObjectCleared()), SIGNAL(initialized())); connect(m_mainFrame, SIGNAL(javaScriptWindowObjectCleared()), SIGNAL(initialized()), Qt::QueuedConnection);
connect(m_webPage, SIGNAL(loadStarted()), SIGNAL(loadStarted())); connect(m_webPage, SIGNAL(loadStarted()), SIGNAL(loadStarted()), Qt::QueuedConnection);
connect(m_webPage, SIGNAL(loadFinished(bool)), SLOT(finish(bool))); connect(m_webPage, SIGNAL(loadFinished(bool)), SLOT(finish(bool)), Qt::QueuedConnection);
// Start with transparent background. // Start with transparent background.
QPalette palette = m_webPage->palette(); QPalette palette = m_webPage->palette();
@ -135,8 +136,6 @@ WebPage::WebPage(QObject *parent, const Config *config)
m_webPage->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true); m_webPage->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true);
m_webPage->settings()->setLocalStoragePath(QDesktopServices::storageLocation(QDesktopServices::DataLocation)); m_webPage->settings()->setLocalStoragePath(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
m_mainFrame->setHtml(BLANK_HTML);
// Custom network access manager to allow traffic monitoring. // Custom network access manager to allow traffic monitoring.
m_networkAccessManager = new NetworkAccessManager(this, config); m_networkAccessManager = new NetworkAccessManager(this, config);
m_webPage->setNetworkAccessManager(m_networkAccessManager); m_webPage->setNetworkAccessManager(m_networkAccessManager);

View File

@ -236,9 +236,16 @@ describe("WebPage construction with options", function () {
}; };
var page = new WebPage(opts); var page = new WebPage(opts);
it("should have onLoadStarted that was specified",function () { it("should have onLoadStarted that was specified",function () {
expect(started).toEqual(false); runs(function() {
page.open("about:blank"); expect(started).toEqual(false);
expect(started).toEqual(true); page.open("about:blank");
});
waits(0);
runs(function() {
expect(started).toEqual(true);
});
}); });
}); });
@ -251,9 +258,16 @@ describe("WebPage construction with options", function () {
}; };
var page = new WebPage(opts); var page = new WebPage(opts);
it("should have onLoadFinished that was specified",function () { it("should have onLoadFinished that was specified",function () {
expect(finished).toEqual(false); runs(function() {
page.open("about:blank"); expect(finished).toEqual(false);
expect(finished).toEqual(true); page.open("about:blank");
});
waits(0);
runs(function() {
expect(finished).toEqual(true);
});
}); });
}); });