Use single quoted strings

This commit is contained in:
Antonin Stefanutti 2016-02-22 10:43:33 +01:00
parent 1abf8df86f
commit 5a55ec24f2
12 changed files with 113 additions and 113 deletions

View File

@ -1,14 +1,14 @@
require.paths.push(phantom.libraryPath + "/libs/");
require.paths.push(phantom.libraryPath + '/libs/');
var page = require("webpage").create(),
printer = require("printer").create(),
system = require("system"),
fs = require("fs"),
Promise = require("promise");
var page = require('webpage').create(),
printer = require('printer').create(),
system = require('system'),
fs = require('fs'),
Promise = require('promise');
// Node to PhantomJS bridging
var process = {
platform: { mac: "darwin", windows: "win32" }[system.os.name] || system.os.name,
platform: { mac: 'darwin', windows: 'win32' }[system.os.name] || system.os.name,
env: system.env,
argv: system.args,
// To uncomment when system.stdout.isTTY is supported
@ -16,96 +16,96 @@ var process = {
exit: phantom.exit
};
// As opposed to PhantomJS, global variables declared in the main script are not accessible in modules loaded with require
if (system.platform === "slimerjs")
if (system.platform === 'slimerjs')
require.globals.process = process;
var plugins = loadAvailablePlugins(phantom.libraryPath + "/plugins/");
var plugins = loadAvailablePlugins(phantom.libraryPath + '/plugins/');
var parser = require("nomnom")
.script("phantomjs decktape.js")
var parser = require('nomnom')
.script('phantomjs decktape.js')
.options({
url: {
position: 1,
required: true,
help: "URL of the slides deck"
help: 'URL of the slides deck'
},
filename: {
position: 2,
required: true,
help: "Filename of the output PDF file"
help: 'Filename of the output PDF file'
},
size: {
abbr: 's',
callback: parseResolution,
transform: parseResolution,
help: "Size of the slides deck viewport: <width>x<height>"
help: 'Size of the slides deck viewport: <width>x<height>'
},
pause: {
abbr: 'p',
default: 1000,
help: "Duration in milliseconds before each slide is exported"
help: 'Duration in milliseconds before each slide is exported'
},
screenshots: {
default: false,
flag: true,
help: "Capture each slide as an image"
help: 'Capture each slide as an image'
},
screenshotDirectory: {
full: "screenshots-directory",
default: "screenshots",
help: "Screenshots output directory"
full: 'screenshots-directory',
default: 'screenshots',
help: 'Screenshots output directory'
},
screenshotSize: {
full: "screenshots-size",
full: 'screenshots-size',
list: true,
callback: parseResolution,
transform: parseResolution,
help: "Screenshots resolution, can be repeated"
help: 'Screenshots resolution, can be repeated'
},
screenshotFormat: {
full: "screenshots-format",
default: "png",
choices: ["jpg", "png"],
help: "Screenshots image format, one of [jpg, png]"
full: 'screenshots-format',
default: 'png',
choices: ['jpg', 'png'],
help: 'Screenshots image format, one of [jpg, png]'
}
});
parser.nocommand()
.help("Defaults to the automatic command.\n" +
"Iterates over the available plugins, picks the compatible one for presentation at the \n" +
"specified <url> and uses it to export and write the PDF into the specified <filename>.");
parser.command("automatic")
.help("Iterates over the available plugins, picks the compatible one for presentation at the \n" +
"specified <url> and uses it to export and write the PDF into the specified <filename>.");
.help('Defaults to the automatic command.\n' +
'Iterates over the available plugins, picks the compatible one for presentation at the \n' +
'specified <url> and uses it to export and write the PDF into the specified <filename>.');
parser.command('automatic')
.help('Iterates over the available plugins, picks the compatible one for presentation at the \n' +
'specified <url> and uses it to export and write the PDF into the specified <filename>.');
Object.keys(plugins).forEach(function (id) {
var command = parser.command(id);
if (typeof plugins[id].options === "object")
if (typeof plugins[id].options === 'object')
command.options(plugins[id].options);
if (typeof plugins[id].help === "string")
if (typeof plugins[id].help === 'string')
command.help(plugins[id].help);
});
// TODO: should be deactivated as well when PhantomJS does not execute in a TTY context
if (system.os.name === "windows")
if (system.os.name === 'windows')
parser.nocolors();
var options = parser.parse(system.args.slice(1));
page.onLoadStarted = function () {
console.log("Loading page " + options.url + " ...");
console.log('Loading page ' + options.url + ' ...');
};
page.onResourceTimeout = function (request) {
console.log("+- Request timeout: " + JSON.stringify(request));
console.log('+- Request timeout: ' + JSON.stringify(request));
};
page.onResourceError = function (resourceError) {
console.log("+- Unable to load resource from URL: " + resourceError.url);
console.log("|_ Error code: " + resourceError.errorCode);
console.log("|_ Description: " + resourceError.errorString);
console.log('+- Unable to load resource from URL: ' + resourceError.url);
console.log('|_ Error code: ' + resourceError.errorCode);
console.log('|_ Description: ' + resourceError.errorString);
};
// PhantomJS emits this event for both pages and frames
page.onLoadFinished = function (status) {
console.log("Loading page finished with status: " + status);
console.log('Loading page finished with status: ' + status);
};
// Must be set before the page is opened
@ -114,25 +114,25 @@ page.onConsoleMessage = function (msg) {
};
page.open(options.url, function (status) {
if (status !== "success") {
console.log("Unable to load the address: " + options.url);
if (status !== 'success') {
console.log('Unable to load the address: ' + options.url);
phantom.exit(1);
} else {
var plugin;
if (!options.command || options.command === "automatic") {
if (!options.command || options.command === 'automatic') {
plugin = createActivePlugin();
if (!plugin) {
console.log("No supported DeckTape plugin detected, falling back to generic plugin");
plugin = plugins["generic"].create(page, options);
console.log('No supported DeckTape plugin detected, falling back to generic plugin');
plugin = plugins['generic'].create(page, options);
}
} else {
plugin = plugins[options.command].create(page, options);
if (!plugin.isActive()) {
console.log("Unable to activate the " + plugin.getName() + " DeckTape plugin for the address: " + options.url);
console.log('Unable to activate the ' + plugin.getName() + ' DeckTape plugin for the address: ' + options.url);
phantom.exit(1);
}
}
console.log(plugin.getName() + " DeckTape plugin activated");
console.log(plugin.getName() + ' DeckTape plugin activated');
configure(plugin);
printer.begin();
exportSlide(plugin);
@ -150,7 +150,7 @@ function loadAvailablePlugins(pluginPath) {
function createActivePlugin() {
for (var id in plugins) {
if (id === "generic")
if (id === 'generic')
continue;
var plugin = plugins[id].create(page, options);
if (plugin.isActive())
@ -172,7 +172,7 @@ function exportSlide(plugin) {
// Delay page rendering to wait for the resize event to complete, e.g. for impress.js (may be needed to be configurable)
.then(delay(1000))
.then(function () {
page.render(options.screenshotDirectory + '/' + options.filename.replace(".pdf", '_' + plugin.currentSlide + '_' + resolution.width + 'x' + resolution.height + '.' + options.screenshotFormat), { onlyViewport: true });
page.render(options.screenshotDirectory + '/' + options.filename.replace('.pdf', '_' + plugin.currentSlide + '_' + resolution.width + 'x' + resolution.height + '.' + options.screenshotFormat), { onlyViewport: true });
})
}, decktape)
.then(function () { page.viewportSize = options.size })
@ -187,7 +187,7 @@ function exportSlide(plugin) {
exportSlide(plugin);
} else {
printer.end();
system.stdout.write("\nPrinted " + plugin.currentSlide + " slides\n");
system.stdout.write('\nPrinted ' + plugin.currentSlide + ' slides\n');
phantom.exit();
}
});
@ -197,7 +197,7 @@ function parseResolution(resolution) {
// TODO: support device viewport sizes and graphics display standard resolutions (see http://viewportsizes.com/ and https://en.wikipedia.org/wiki/Graphics_display_resolution)
var match = resolution.match(/^(\d+)x(\d+)$/);
if (!match)
return "Resolution must follow the <width>x<height> notation, e.g., 1280x720";
return 'Resolution must follow the <width>x<height> notation, e.g., 1280x720';
else
return { width: match[1], height: match[2] };
}
@ -206,21 +206,21 @@ function parseResolution(resolution) {
function progressBar(plugin) {
var cols = [];
var index = currentSlideIndex(plugin);
cols.push("Printing slide ");
cols.push('Printing slide ');
cols.push(padding('#' + index, 8, ' ', false));
cols.push(" (");
cols.push(' (');
cols.push(padding(plugin.currentSlide, plugin.totalSlides ? plugin.totalSlides.toString().length : 3, ' '));
cols.push('/');
cols.push(plugin.totalSlides || " ?");
cols.push(") ...");
cols.push(plugin.totalSlides || ' ?');
cols.push(') ...');
// erase overflowing slide fragments
cols.push(padding("", plugin.progressBarOverflow - Math.max(index.length + 1 - 8, 0), ' ', false));
cols.push(padding('', plugin.progressBarOverflow - Math.max(index.length + 1 - 8, 0), ' ', false));
plugin.progressBarOverflow = Math.max(index.length + 1 - 8, 0);
return cols.join('');
}
function padding(str, len, char, left) {
if (typeof str === "number")
if (typeof str === 'number')
str = str.toString();
var l = len - str.length;
var p = [];
@ -240,17 +240,17 @@ function delay(time) {
}
var configure = function (plugin) {
if (!options.size && typeof plugin.size === "function")
if (!options.size && typeof plugin.size === 'function')
options.size = plugin.size();
if (!options.size)
options.size = { width: 1280, height: 720 };
page.viewportSize = options.size;
printer.paperSize = { width: options.size.width + "px", height: options.size.height + "px", margin: "0px" };
printer.paperSize = { width: options.size.width + 'px', height: options.size.height + 'px', margin: '0px' };
printer.outputFileName = options.filename;
plugin.progressBarOverflow = 0;
plugin.currentSlide = 1;
plugin.totalSlides = slideCount(plugin);
if (typeof plugin.configure === "function")
if (typeof plugin.configure === 'function')
return plugin.configure();
};
@ -259,7 +259,7 @@ var slideCount = function (plugin) {
};
var hasNextSlide = function (plugin) {
if (typeof plugin.hasNextSlide === "function")
if (typeof plugin.hasNextSlide === 'function')
return plugin.hasNextSlide();
else
return plugin.currentSlide < plugin.totalSlides;

View File

@ -1,6 +1,6 @@
exports.create = function(page) {
return {
getName: function() { return "Bespoke.js"; },
getName: function() { return 'Bespoke.js'; },
isActive: function() { return page.evaluate(function() { return !!((window.bespoke||{}).deck ? (deck = bespoke.deck) : 0); }); },
size: function() { return page.evaluate(function() {
var style = getComputedStyle(deck.slides[0]);

View File

@ -5,25 +5,25 @@ function CSSS(page) {
CSSS.prototype = {
getName: function () {
return "CSSS";
return 'CSSS';
},
isActive: function () {
return this.page.evaluate(function () {
// Avoid global variable name collision with remark.js
return typeof remark === "undefined" && typeof slideshow === "object";
return typeof remark === 'undefined' && typeof slideshow === 'object';
});
},
configure: function () {
this.page.evaluate(function () {
document.getElementById("timer").style.display = "none";
document.getElementById('timer').style.display = 'none';
});
},
slideCount: function () {
return this.page.evaluate(function () {
return document.querySelectorAll(".slide, .delayed, .delayed-children > *").length;
return document.querySelectorAll('.slide, .delayed, .delayed-children > *').length;
});
},

View File

@ -5,30 +5,30 @@ function Deck(page) {
Deck.prototype = {
getName: function () {
return "Deck JS";
return 'Deck JS';
},
isActive: function () {
return this.page.evaluate(function () {
return typeof $ === "function" && typeof $.deck === "function";
return typeof $ === 'function' && typeof $.deck === 'function';
});
},
slideCount: function () {
return this.page.evaluate(function () {
return $.deck("getSlides").length;
return $.deck('getSlides').length;
});
},
nextSlide: function () {
this.page.evaluate(function () {
$.deck("next");
$.deck('next');
});
},
currentSlideIndex: function () {
return this.page.evaluate(function () {
return $.deck("getSlide").attr("id");
return $.deck('getSlide').attr('id');
});
}
};

View File

@ -5,12 +5,12 @@ function DZSlides(page) {
DZSlides.prototype = {
getName: function () {
return "DZ Slides";
return 'DZ Slides';
},
isActive: function () {
return this.page.evaluate(function () {
return typeof Dz !== "undefined";
return typeof Dz !== 'undefined';
});
},
@ -37,7 +37,7 @@ DZSlides.prototype = {
currentSlideIndex: function () {
return this.page.evaluate(function () {
return Dz.idx + "." + Dz.step;
return Dz.idx + '.' + Dz.step;
});
}
};

View File

@ -5,12 +5,12 @@ function Flowtime(page) {
Flowtime.prototype = {
getName: function () {
return "Flowtime JS";
return 'Flowtime JS';
},
isActive: function () {
return this.page.evaluate(function () {
return typeof Flowtime === "object";
return typeof Flowtime === 'object';
});
},
@ -39,7 +39,7 @@ Flowtime.prototype = {
currentSlideIndex: function () {
return this.page.evaluate(function () {
return "/section-" + (Flowtime.getSectionIndex() + 1) + "/page-" + (Flowtime.getPageIndex() + 1);
return '/section-' + (Flowtime.getSectionIndex() + 1) + '/page-' + (Flowtime.getPageIndex() + 1);
});
}
};

View File

@ -3,21 +3,21 @@
exports.options = {
keycode: {
default: "Right",
help: "Key code pressed to navigate to next slide"
default: 'Right',
help: 'Key code pressed to navigate to next slide'
},
maxSlides: {
help: "Maximum number of slides to export"
help: 'Maximum number of slides to export'
}
};
exports.help =
"Emulates the end-user interaction by pressing the key with the specified [keycode] option\n" +
"and iterates over the presentation as long as:\n" +
"- Any change to the DOM is detected by observing mutation events targeting the body element\n" +
" and its subtree,\n" +
"- Nor the number of slides exported has reached the specified [maxSlides] option.\n" +
"The [keycode] option must be one of the PhantomJS page event keys and defaults to [Right].";
'Emulates the end-user interaction by pressing the key with the specified [keycode] option\n' +
'and iterates over the presentation as long as:\n' +
'- Any change to the DOM is detected by observing mutation events targeting the body element\n' +
' and its subtree,\n' +
'- Nor the number of slides exported has reached the specified [maxSlides] option.\n' +
'The [keycode] option must be one of the PhantomJS page event keys and defaults to [Right].';
exports.create = function (page, options) {
return new Generic(page, options);
@ -33,7 +33,7 @@ function Generic(page, options) {
Generic.prototype = {
getName: function () {
return "Generic";
return 'Generic';
},
isActive: function () {
@ -45,7 +45,7 @@ Generic.prototype = {
var observer = new window.MutationObserver(function () {
window.callPhantom({ isNextSlideDetected: true });
});
observer.observe(document.querySelector("body"), { attributes: true, childList: true, subtree: true });
observer.observe(document.querySelector('body'), { attributes: true, childList: true, subtree: true });
});
var plugin = this;
this.page.onCallback = function (mutation) {
@ -63,7 +63,7 @@ Generic.prototype = {
if (this.options.maxSlides && this.currentSlide >= this.options.maxSlides)
return false;
// PhantomJS actually sends a 'keydown' DOM event when sending a 'keypress' user event. Hence 'keypress' event is skipped to avoid moving forward two steps instead of one. See https://github.com/ariya/phantomjs/issues/11094 for more details.
["keydown"/*, "keypress"*/, "keyup"].forEach(function (event) {
['keydown'/*, 'keypress'*/, 'keyup'].forEach(function (event) {
this.page.sendEvent(event, this.keycode);
}, this);
var plugin = this;
@ -82,7 +82,7 @@ Generic.prototype = {
currentSlideIndex: function () {
var fragment = this.page.evaluate(function () {
return window.location.hash.replace(/^#\/?/, "");
return window.location.hash.replace(/^#\/?/, '');
});
return fragment.length ? fragment : this.currentSlide;
}

View File

@ -5,16 +5,16 @@ function Impress(page) {
Impress.prototype = {
getName: function () {
return "Impress JS";
return 'Impress JS';
},
isActive: function () {
return this.page.evaluate(function () {
if (typeof impress === "function")
if (typeof impress === 'function')
return true;
if (document.getElementById("impress"))
console.log("Impress JS plugin isn't compatible with impress.js version < 0.3.0");
if (document.getElementById('impress'))
console.log('Impress JS plugin isn\'t compatible with impress.js version < 0.3.0');
return false;
});
@ -22,7 +22,7 @@ Impress.prototype = {
slideCount: function () {
return this.page.evaluate(function () {
return document.querySelectorAll("#impress .step, #impress .substep").length;
return document.querySelectorAll('#impress .step, #impress .substep').length;
});
},
@ -34,7 +34,7 @@ Impress.prototype = {
currentSlideIndex: function () {
return this.page.evaluate(function () {
return window.location.hash.replace(/^#\/?/, "");
return window.location.hash.replace(/^#\/?/, '');
});
}
};

View File

@ -6,12 +6,12 @@ function Remark(page) {
Remark.prototype = {
getName: function () {
return "Remark JS";
return 'Remark JS';
},
isActive: function () {
return this.page.evaluate(function () {
return typeof remark === "object" && typeof slideshow === "object";
return typeof remark === 'object' && typeof slideshow === 'object';
});
},

View File

@ -5,16 +5,16 @@ function Reveal(page) {
Reveal.prototype = {
getName: function () {
return "Reveal JS";
return 'Reveal JS';
},
isActive: function () {
return this.page.evaluate(function () {
if (typeof Reveal === "undefined")
if (typeof Reveal === 'undefined')
return false;
if (!(typeof Reveal.isLastSlide === "function")) {
console.log("Reveal JS plugin isn't compatible with reveal.js version < 2.3.0");
if (!(typeof Reveal.isLastSlide === 'function')) {
console.log('Reveal JS plugin isn\'t compatible with reveal.js version < 2.3.0');
return false;
}
@ -32,7 +32,7 @@ Reveal.prototype = {
return this.page.evaluate(function () {
// TODO: the getTotalSlides API does not report the number of slides accurately as it does not take stacks and some index-less fragments into account
// getTotalSlides API is only available starting reveal.js version 3.0.0
return typeof Reveal.getTotalSlides === "function" ? Reveal.getTotalSlides() : undefined;
return typeof Reveal.getTotalSlides === 'function' ? Reveal.getTotalSlides() : undefined;
});
},
@ -51,8 +51,8 @@ Reveal.prototype = {
currentSlideIndex: function () {
return this.page.evaluate(function () {
var indices = Reveal.getIndices();
var id = Reveal.getCurrentSlide().getAttribute("id");
if (typeof id === "string" && id.length)
var id = Reveal.getCurrentSlide().getAttribute('id');
if (typeof id === 'string' && id.length)
return '/' + id;
else
return '/' + indices.h + (indices.v > 0 ? '/' + indices.v : '');

View File

@ -5,12 +5,12 @@ function Shower(page) {
Shower.prototype = {
getName: function () {
return "Shower";
return 'Shower';
},
isActive: function () {
return this.page.evaluate(function () {
return typeof shower === "object";
return typeof shower === 'object';
});
},

View File

@ -5,26 +5,26 @@ function Slidy(page) {
Slidy.prototype = {
getName: function () {
return "HTML Slidy";
return 'HTML Slidy';
},
isActive: function () {
return this.page.evaluate(function () {
return typeof w3c_slidy === "object";
return typeof w3c_slidy === 'object';
});
},
configure: function () {
this.page.evaluate(function () {
w3c_slidy.hide_toolbar();
w3c_slidy.initial_prompt.style.visibility = "hidden";
w3c_slidy.initial_prompt.style.visibility = 'hidden';
});
},
slideCount: function () {
return this.page.evaluate(function () {
return w3c_slidy.slides.length + Array.prototype.slice.call(document.querySelectorAll(".incremental")).reduce(function (incrementals, parent) {
var children = parent.querySelectorAll("*");
return w3c_slidy.slides.length + Array.prototype.slice.call(document.querySelectorAll('.incremental')).reduce(function (incrementals, parent) {
var children = parent.querySelectorAll('*');
return incrementals + (children.length == 0 ? 1 : children.length);
}, 0);
});
@ -44,7 +44,7 @@ Slidy.prototype = {
currentSlideIndex: function () {
return this.page.evaluate(function () {
return "(" + (w3c_slidy.slide_number + 1) + ")";
return '(' + (w3c_slidy.slide_number + 1) + ')';
});
}
};