From 58566bbe76d1da4db779eeac1524b58257476a70 Mon Sep 17 00:00:00 2001 From: Dody Suria Wijaya Date: Fri, 1 Feb 2013 19:56:31 -0600 Subject: [PATCH] Fix concurrent issue on render_multi_url example webkit (thus phantomjs) load() does not call loadFinished at the expected timing when running concurrently. The example is changed to run non-concurrently as a work around. Issue: http://code.google.com/p/phantomjs/issues/detail?id=1021 --- examples/render_multi_url.coffee | 88 +++++++++++++----------- examples/render_multi_url.js | 111 +++++++++++++++++-------------- 2 files changed, 110 insertions(+), 89 deletions(-) diff --git a/examples/render_multi_url.coffee b/examples/render_multi_url.coffee index 8f673c76..29afa48f 100644 --- a/examples/render_multi_url.coffee +++ b/examples/render_multi_url.coffee @@ -1,50 +1,60 @@ # Render Multiple URLs to file -# FIXME: For now it is fine with pure domain names: don't think it would work with paths and stuff like that -system = require 'system' +system = require("system") -# Extend the Array Prototype with a 'foreach' -Array.prototype.forEach = (action) -> - for i, j in this - action j, i, _len - -# Render a given url to a given file -# @param url URL to render -# @param file File to render to -# @param callback Callback function -renderUrlToFile = (url, file, callback) -> - page = require('webpage').create() - page.viewportSize = { width: 800, height : 600 } - page.settings.userAgent = 'Phantom.js bot' - - page.open url, (status) -> - if status isnt 'success' - console.log "Unable to render '#{url}'" - else - page.render file +# Render given urls +# @param array of URLs to render +# @param callbackPerUrl Function called after finishing each URL, including the last URL +# @param callbackFinal Function called after finishing everything +RenderUrlsToFile = (urls, callbackPerUrl, callbackFinal) -> + urlIndex = 0 # only for easy file naming + webpage = require("webpage") + page = null + getFilename = -> + "rendermulti-" + urlIndex + ".png" + next = (status, url, file) -> page.close() - callback url, file + callbackPerUrl status, url, file + retrieve() -# Read the passed args + retrieve = -> + if urls.length > 0 + url = urls.shift() + urlIndex++ + page = webpage.create() + page.viewportSize = + width: 800 + height: 600 + + page.settings.userAgent = "Phantom.js bot" + page.open "http://" + url, (status) -> + file = getFilename() + if status is "success" + window.setTimeout (-> + page.render file + next status, url, file + ), 200 + else + next status, url, file + + else + callbackFinal() + + retrieve() +arrayOfUrls = null if system.args.length > 1 - arrayOfUrls = Array.prototype.slice.call system.args, 1 + arrayOfUrls = Array::slice.call(system.args, 1) else # Default (no args passed) - console.log 'Usage: phantomjs render_multi_url.coffee [domain.name1, domain.name2, ...]' - arrayOfUrls = [ - 'www.google.com', - 'www.bbc.co.uk', - 'www.phantomjs.org' - ] + console.log "Usage: phantomjs render_multi_url.js [domain.name1, domain.name2, ...]" + arrayOfUrls = ["www.google.com", "www.bbc.co.uk", "www.phantomjs.org"] -# For each URL -arrayOfUrls.forEach (pos, url, total) -> - file_name = "./#{url}.png" +RenderUrlsToFile arrayOfUrls, ((status, url, file) -> + if status isnt "success" + console.log "Unable to render '" + url + "'" + else + console.log "Rendered '" + url + "' at '" + file + "'" +), -> + phantom.exit() - # Render to a file - renderUrlToFile "http://#{url}", file_name, (url, file) -> - console.log "Rendered '#{url}' at '#{file}'" - if pos is total - 1 - # Close Phantom if it's the last URL - phantom.exit() diff --git a/examples/render_multi_url.js b/examples/render_multi_url.js index 3ae42402..df098137 100644 --- a/examples/render_multi_url.js +++ b/examples/render_multi_url.js @@ -1,62 +1,73 @@ // Render Multiple URLs to file -// FIXME: For now it is fine with pure domain names: don't think it would work with paths and stuff like that -var system = require('system'); +var RenderUrlsToFile, arrayOfUrls, system; -// Extend the Array Prototype with a 'foreach' -Array.prototype.forEach = function (action) { - var i, len; - for ( i = 0, len = this.length; i < len; ++i ) { - action(i, this[i], len); - } +system = require("system"); + +/* +Render given urls +@param array of URLs to render +@param callbackPerUrl Function called after finishing each URL, including the last URL +@param callbackFinal Function called after finishing everything +*/ +RenderUrlsToFile = function(urls, callbackPerUrl, callbackFinal) { + var getFilename, next, page, retrieve, urlIndex, webpage; + urlIndex = 0; + webpage = require("webpage"); + page = null; + getFilename = function() { + return "rendermulti-" + urlIndex + ".png"; + }; + next = function(status, url, file) { + page.close(); + callbackPerUrl(status, url, file); + return retrieve(); + }; + retrieve = function() { + var url; + if (urls.length > 0) { + url = urls.shift(); + urlIndex++; + page = webpage.create(); + page.viewportSize = { + width: 800, + height: 600 + }; + page.settings.userAgent = "Phantom.js bot"; + return page.open("http://" + url, function(status) { + var file; + file = getFilename(); + if (status === "success") { + return window.setTimeout((function() { + page.render(file); + return next(status, url, file); + }), 200); + } else { + return next(status, url, file); + } + }); + } else { + return callbackFinal(); + } + }; + return retrieve(); }; -/** - * Render a given url to a given file - * @param url URL to render - * @param file File to render to - * @param callback Callback function - */ -function renderUrlToFile(url, file, callback) { - var page = require('webpage').create(); - page.viewportSize = { width: 800, height : 600 }; - page.settings.userAgent = "Phantom.js bot"; +arrayOfUrls = null; - page.open(url, function(status){ - if ( status !== "success") { - console.log("Unable to render '"+url+"'"); - } else { - page.render(file); - } - page.close(); - callback(url, file); - }); -} - -// Read the passed args -var arrayOfUrls; -if ( system.args.length > 1 ) { +if (system.args.length > 1) { arrayOfUrls = Array.prototype.slice.call(system.args, 1); } else { - // Default (no args passed) console.log("Usage: phantomjs render_multi_url.js [domain.name1, domain.name2, ...]"); - arrayOfUrls = [ - 'www.google.com', - 'www.bbc.co.uk', - 'www.phantomjs.org' - ]; + arrayOfUrls = ["www.google.com", "www.bbc.co.uk", "www.phantomjs.org"]; } -// For each URL -arrayOfUrls.forEach(function(pos, url, total){ - var file_name = "./" + url + ".png"; - - // Render to a file - renderUrlToFile("http://"+url, file_name, function(url, file){ - console.log("Rendered '"+url+"' at '"+file+"'"); - if ( pos === total-1 ) { - // Close Phantom if it's the last URL - phantom.exit(); - } - }); +RenderUrlsToFile(arrayOfUrls, (function(status, url, file) { + if (status !== "success") { + return console.log("Unable to render '" + url + "'"); + } else { + return console.log("Rendered '" + url + "' at '" + file + "'"); + } +}), function() { + return phantom.exit(); });