From dca15d7ff69bf3e3e8f335219ba3ff4100517564 Mon Sep 17 00:00:00 2001 From: James McParlane Date: Tue, 3 Dec 2013 15:08:47 +1100 Subject: [PATCH] Added onRepaint callback to webpage API. Enables subscription to RepaintRequested events. When the callback is invoked the time that the repaint was requested as well as the x,y and width,height of the repainted rectangle are provided as parameters. Usage: page.onRepaint = function(time, x, y, width, height) { } https://github.com/ariya/phantomjs/issues/11793 --- examples/page_events.coffee | 6 +++++- examples/page_events.js | 4 ++++ src/modules/webpage.js | 10 ++++++---- src/webpage.cpp | 22 +++++++++++++++------- src/webpage.h | 2 ++ test/webpage-spec.js | 27 +++++++++++++++++++++++++-- 6 files changed, 57 insertions(+), 14 deletions(-) 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();