diff --git a/examples/page_events.coffee b/examples/page_events.coffee index 87e433b0..505466fd 100644 --- a/examples/page_events.coffee +++ b/examples/page_events.coffee @@ -56,6 +56,10 @@ page.onNavigationRequested = -> console.log "page.onNavigationRequested" printArgs.apply this, arguments_ +page.onRepaintRequested = -> + console.log "page.onRepaintRequested" + printArgs.apply this, arguments_ + if logResources is true page.onResourceRequested = -> console.log "page.onResourceRequested" @@ -129,4 +133,4 @@ setTimeout (-> setTimeout (-> phantom.exit() ), 100 -), 20000 \ No newline at end of file +), 20000 diff --git a/examples/page_events.js b/examples/page_events.js index 266b4048..31e36286 100644 --- a/examples/page_events.js +++ b/examples/page_events.js @@ -59,6 +59,10 @@ page.onNavigationRequested = function() { console.log("page.onNavigationRequested"); printArgs.apply(this, arguments); }; +page.onRepaintRequested = function() { + console.log("page.onRepaintRequested"); + printArgs.apply(this, arguments); +}; if (logResources === true) { page.onResourceRequested = function() { diff --git a/src/modules/webpage.js b/src/modules/webpage.js index d39ff5b1..095e186b 100644 --- a/src/modules/webpage.js +++ b/src/modules/webpage.js @@ -110,7 +110,7 @@ function definePageSignalHandler(page, handlers, handlerName, signalName) { this[signalName].connect(f); } }); - + page.__defineGetter__(handlerName, function() { return !!handlers[handlerName] && typeof handlers[handlerName].callback === "function" ? handlers[handlerName].callback : @@ -142,7 +142,7 @@ function definePageCallbackHandler(page, handlers, handlerName, callbackConstruc // Callback will receive a "deserialized", normal "arguments" array callbackObj.returnValue = f.apply(this, arguments[0]); }; - + // Store the new handler for reference handlers[handlerName] = { callback: f, @@ -153,7 +153,7 @@ function definePageCallbackHandler(page, handlers, handlerName, callbackConstruc callbackObj.called.connect(connector); } }); - + page.__defineGetter__(handlerName, function() { var handlerObj = handlers[handlerName]; return (!!handlerObj && typeof handlerObj.callback === "function" && typeof handlerObj.connector === "function") ? @@ -248,10 +248,12 @@ function decorateNewPage(opts, page) { definePageSignalHandler(page, handlers, "onNavigationRequested", "navigationRequested"); + definePageSignalHandler(page, handlers, "onRepaintRequested", "repaintRequested"); + definePageSignalHandler(page, handlers, "onResourceRequested", "resourceRequested"); definePageSignalHandler(page, handlers, "onResourceReceived", "resourceReceived"); - + definePageSignalHandler(page, handlers, "onResourceError", "resourceError"); definePageSignalHandler(page, handlers, "onResourceTimeout", "resourceTimeout"); diff --git a/src/webpage.cpp b/src/webpage.cpp index b4fa83d2..b29c4053 100644 --- a/src/webpage.cpp +++ b/src/webpage.cpp @@ -198,7 +198,7 @@ protected: break; } bool isNavigationLocked = m_webPage->navigationLocked(); - + emit m_webPage->navigationRequested( request.url(), //< Requested URL navigationType, //< Navigation Type @@ -295,7 +295,7 @@ public: } return m_jsPromptCallback; } - + QObject *getJsInterruptCallback() { qDebug() << "WebpageCallbacks - getJsInterruptCallback"; @@ -363,6 +363,8 @@ WebPage::WebPage(QObject *parent, const QUrl &baseUrl) connect(m_customWebPage, SIGNAL(loadFinished(bool)), SLOT(finish(bool)), Qt::QueuedConnection); connect(m_customWebPage, SIGNAL(windowCloseRequested()), this, SLOT(close()), Qt::QueuedConnection); connect(m_customWebPage, SIGNAL(loadProgress(int)), this, SLOT(updateLoadingProgress(int))); + connect(m_customWebPage, SIGNAL(repaintRequested(QRect)), this, SLOT(handleRepaintRequested(QRect)), Qt::QueuedConnection); + // Start with transparent background. QPalette palette = m_customWebPage->palette(); @@ -939,12 +941,12 @@ bool WebPage::render(const QString &fileName, const QVariantMap &option) } if( tempFileName != "" ){ - // cleanup temporary file and render to stdout or stderr + // cleanup temporary file and render to stdout or stderr QFile i(tempFileName); i.open(QIODevice::ReadOnly); - + QByteArray ba = i.readAll(); - + System *system = (System*)Phantom::instance()->createSystem(); if( fileName == STDOUT_FILENAME ){ #ifdef Q_OS_WIN32 @@ -955,7 +957,7 @@ bool WebPage::render(const QString &fileName, const QVariantMap &option) #ifdef Q_OS_WIN32 _setmode(_fileno(stdout), O_TEXT); -#endif +#endif } else if( fileName == STDERR_FILENAME ){ #ifdef Q_OS_WIN32 @@ -966,7 +968,7 @@ bool WebPage::render(const QString &fileName, const QVariantMap &option) #ifdef Q_OS_WIN32 _setmode(_fileno(stderr), O_TEXT); -#endif +#endif } i.close(); @@ -1617,6 +1619,12 @@ void WebPage::updateLoadingProgress(int progress) m_loadingProgress = progress; } +void WebPage::handleRepaintRequested(const QRect &dirtyRect) +{ + emit repaintRequested(dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height()); +} + + void WebPage::stopJavaScript() { m_shouldInterruptJs = true; diff --git a/src/webpage.h b/src/webpage.h index ad1b7026..c1ffbedf 100644 --- a/src/webpage.h +++ b/src/webpage.h @@ -477,11 +477,13 @@ signals: void navigationRequested(const QUrl &url, const QString &navigationType, bool navigationLocked, bool isMainFrame); void rawPageCreated(QObject *page); void closing(QObject *page); + void repaintRequested(const int x, const int y, const int width, const int height); private slots: void finish(bool ok); void setupFrame(QWebFrame *frame = NULL); void updateLoadingProgress(int progress); + void handleRepaintRequested(const QRect &dirtyRect); private: QImage renderImage(); diff --git a/test/webpage-spec.js b/test/webpage-spec.js index 11654285..18e13f86 100644 --- a/test/webpage-spec.js +++ b/test/webpage-spec.js @@ -1394,11 +1394,11 @@ describe("WebPage object", function() { 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'); }); @@ -2025,6 +2025,29 @@ describe('WebPage navigation events', function() { }); }); + +describe('WebPage repaint requests', function() { + it('should report when a repaint is requested, together with the area being repainted', function () { + var page = require("webpage").create(); + var base = "https://github.com"; + var isHandled = false; + + runs(function() { + page.onRepaintRequested = function(x, y, width, height) { + isHandled = true; + }; + + page.open(base); + }); + + waits(3000); + + runs(function() { + expect(isHandled).toEqual(true); + }); + }); +}); + describe("WebPage loading/loadingProgress properties", function() { var p = require("webpage").create();