docpad-plugin-livereload
Version:
Automatically refreshes your website whenever a rengeration is performed
185 lines (174 loc) • 5.44 kB
JavaScript
// Generated by CoffeeScript 2.5.1
// Export Plugin
module.exports = function(BasePlugin) {
var LivereloadPlugin;
return LivereloadPlugin = (function() {
// Define Plugin
class LivereloadPlugin extends BasePlugin {
// Populate Collections
// Used to inject our scripts block with our socket generate listener
populateCollections(opts) {
var config, docpad, generateAfterBlock, generateBeforeBlock, injectBlock, listenBlock, scriptBlock, styleBlock;
// Prepare
docpad = this.docpad;
config = this.getConfig();
// Blocks
generateBeforeBlock = config.generateBeforeBlock || `if ( typeof document.getElementsByTagName !== 'undefined' ) {
document.getElementsByTagName('html')[0].className += ' wait';
}`;
generateAfterBlock = config.generateAfterBlock || `document.location.reload();`;
listenBlock = config.listenBlock || `/* Did we just livereload? */
var log = !!(localStorage && console && console.log && true);
if ( log && localStorage.getItem('${config.channel}/reloaded') === 'yes' ) {
localStorage.removeItem('${config.channel}/reloaded');
console.log('LiveReload completed at', new Date())
}
/* Listen for the regenerated event and perform a reload of the page when the event occurs */
var listen = function(){
var primus = new Primus('${config.channel}');
primus.on('data', function(data){
if ( data && data.message ) {
if ( data.message === 'generateBefore' ) {
if ( log ) {
console.log('LiveReload started at', new Date());
}
${generateBeforeBlock}
}
else if ( data.message === 'generateAfter' ) {
if ( log ) {
localStorage.setItem('${config.channel}/reloaded', 'yes');
}
${generateAfterBlock}
}
}
});
};`;
injectBlock = config.injectBlock || `/* Inject socket into our page */
var inject = function(){
var t = document.createElement('script');
t.type = 'text/javascript';
t.async = 'async';
t.src = '${config.pathname}/primus.js';
t.onload = listen;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(t, s);
};`;
scriptBlock = config.scriptBlock || (config.inject ? `(function(){
${listenBlock}
${injectBlock}
if ( typeof Primus !== 'undefined' ) {
listen();
} else {
inject();
}
})();` : `(function(){
${listenBlock}
if ( typeof Primus !== 'undefined' ) {
listen();
}
})();`);
styleBlock = config.styleBlock || `html.wait {
cursor: wait !important;
opacity: 0;
transition: opacity 0.5s ease;
}`;
// Script
docpad.getBlock('scripts').add(scriptBlock, {
defer: false
});
// Style
docpad.getBlock('styles').add(styleBlock);
return this;
}
// Setup Extend
// Start our socket
serverExtend(opts) {
var Primus, config, docpad, extendr, plugin, serverHttp, socketOptions;
// Prepare
({serverHttp} = opts);
plugin = this;
docpad = this.docpad;
config = this.getConfig();
// Configuration
extendr = require('extendr');
socketOptions = extendr.deep({}, config.socketOptions, {
pathname: config.pathname
});
// Get socket using custom method if set
this.socket = typeof config.getSocket === "function" ? config.getSocket(opts, socketOptions) : void 0;
if (this.socket) {
docpad.log('info', `LiveReload listening to custom socket on channel ${config.channel}`);
} else {
// Create a socket using primus
Primus = require('primus');
this.socket = new Primus(serverHttp, socketOptions);
this.socket.on('error', docpad.warn);
// Log
docpad.log('info', `LiveReload listening to new socket on channel ${config.channel}`);
}
return this;
}
// Generate Before
generateBefore() {
var ref;
// Notify client
if ((ref = this.socket) != null) {
ref.write({
message: 'generateBefore'
});
}
return this;
}
// Generate After
generateAfter() {
var ref;
// Notify client
if ((ref = this.socket) != null) {
ref.write({
message: 'generateAfter'
});
}
return this;
}
// DocPad Destroy
docpadDestroy() {
var ref;
// Destroy the sockets
if ((ref = this.socket) != null) {
ref.destroy({
close: false, // Close the HTTP server that Primus received
end: true // End all active connections
});
}
return this;
}
};
// Plugin configuration
LivereloadPlugin.prototype.name = 'livereload';
// Plugin configuration
// Only enable us on the development environment
LivereloadPlugin.prototype.config = {
channel: '/docpad-livereload',
pathname: '/docpad-livereload',
enabled: false,
getSocket: null,
inject: true,
generateBeforeBlock: null,
generateAfterBlock: null,
listenBlock: null,
injectBlock: null,
scriptBlock: null,
styleBlock: null,
socketOptions: {
transformer: 'websockets',
parser: 'JSON'
},
environments: {
development: {
enabled: true
}
}
};
return LivereloadPlugin;
}).call(this);
};