UNPKG

phantomjs-render-large-page

Version:

PhantomJS can’t render very tall or wide pages (more than 30k pixels). This library is a workaround to do it anyway.

96 lines (83 loc) 3.43 kB
'use strict'; var fs = require('fs'); var system = require('system'); var execFile = require('child_process').execFile; var Promise = require('promise-polyfill'); function findPageDimensions(page) { return page.evaluate(function () { var body = document.body, html = document.documentElement; var height = Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight ); var width = Math.max( body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth ); return {width: width, height: height}; }); } function childPromise(command, args) { return new Promise(function (resolve, reject) { execFile(command, args, null, function (err, stdout, stderr) { if (err) { reject(err + JSON.stringify(stderr)); } else { resolve(); } }); }); } module.exports.renderLargePage = function (phantomJsPage, filename, callback, options) { callback = callback || function () {}; options = options || {}; var tmpDir = options.tmpDir || system.env.TMPDIR || '/tmp'; var format = options.format || 'png'; var limit = 30720; var quality = options.quality || 100; var parsedOptionsLimit = parseInt(options.limit, 10); if (options.limit && !isNaN(parsedOptionsLimit)) { limit = parsedOptionsLimit; } var tempDir = tmpDir + '/phantomjs-render-large-page_tmp_' + system.pid; if (!fs.makeTree(tempDir)) { throw new Error('phantomjs-render-large-page Error couldn\'t create directory ' + tempDir); } var dimensions = findPageDimensions(phantomJsPage); var filesColumns = [[]], filesCells; var i,j, name; for (i=0; i < dimensions.width; i += limit) { filesCells = filesColumns[filesColumns.length-1]; for (j=0; j < dimensions.height; j += limit) { phantomJsPage.clipRect = { left: i, top: j, width: Math.min(limit, dimensions.width - i), height: Math.min(limit, dimensions.height - j) }; name = tempDir + '/cell_' + i + '_' + j + '.' + format; phantomJsPage.render(name, format, quality); filesCells.push(name); } filesColumns.push([]); } filesColumns.pop(); return Promise.all(filesColumns.map(function (cellFilenames, columnIndex) { return Promise.all(cellFilenames.map(function (cellFilename) { return childPromise('convert', [cellFilename, cellFilename + '.mpc']).then(function (code) { return cellFilename + '.mpc'; }); })).then(function (cellFilenamesMpc) { var columnFilenameMpc = tempDir + '/column_' + columnIndex + '.mpc'; return childPromise('convert', cellFilenamesMpc.concat(['-append', columnFilenameMpc])).then(function (code) { return columnFilenameMpc; }); }); })).then(function (columnFilenamesMpc) { return childPromise('convert', columnFilenamesMpc.concat(['-quality', '' + quality, '+append', filename])).then(function (code) { fs.removeTree(tempDir); callback(); return filename; }); }).catch(function (error) { callback(error); }); };