mirror of
https://github.com/remy/inliner.git
synced 2024-09-11 17:25:30 +03:00
pre white space now remains intact, inliner executable supports more options on command line - in addition to optionally not base64 encoding images.
This commit is contained in:
parent
1417f2d28e
commit
7c9b89f0a9
94
bin/inliner
94
bin/inliner
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var path = require('path'), fs = require('fs');
|
||||
var path = require('path'), fs = require('fs'), querystring = require('querystring');
|
||||
|
||||
fs.realpath(__filename, function(error, script) {
|
||||
var servedir, root, port;
|
||||
@ -14,55 +14,109 @@ fs.realpath(__filename, function(error, script) {
|
||||
'',
|
||||
'Options:',
|
||||
' --verbose echo on STDERR the progress of inlining',
|
||||
// ' --share save the output on jsbin.com and return a shareable url',
|
||||
' --nocompress don\'t compress CSS or HTML - useful for debugging',
|
||||
' --images don\'t encode images - keeps files size small, but more requests',
|
||||
' --version current inliner version',
|
||||
' --help this usage',
|
||||
'',
|
||||
'For more details see http://github.com/remy/inliner/\n'
|
||||
].join('\n');
|
||||
|
||||
if (process.argv[2] === undefined) {
|
||||
console.log(usage);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
function controlArg(args, label, fn) {
|
||||
var i;
|
||||
|
||||
var callback = function (arg, i) {
|
||||
args.splice(i, 1);
|
||||
fn(arg, i);
|
||||
};
|
||||
|
||||
if ((i = args.indexOf(label)) !== -1) {
|
||||
fn(args[i], i);
|
||||
callback(args[i], i);
|
||||
} else if ((i = args.indexOf('-' + label.substr(0, 1))) !== -1) {
|
||||
fn(args[i], i);
|
||||
callback(args[i], i);
|
||||
} else if ((i = args.indexOf('--' + label)) !== -1) {
|
||||
fn(args[i], i);
|
||||
callback(args[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
var options,
|
||||
verbose = false;
|
||||
var options = Inliner.defaults,
|
||||
verbose = false,
|
||||
share = false;
|
||||
|
||||
controlArg(process.argv, 'help', function () {
|
||||
console.log(usage);
|
||||
process.exit();
|
||||
});
|
||||
|
||||
controlArg(process.argv, 'version', function () {
|
||||
console.log(Inliner.version);
|
||||
process.exit();
|
||||
controlArg(process.argv, 'nocompress', function (arg, i) {
|
||||
options.compressCSS = false;
|
||||
options.collapseWhitespace = false;
|
||||
});
|
||||
|
||||
controlArg(process.argv, 'nocompress', function (arg, i) {
|
||||
process.argv.splice(i, 1);
|
||||
options = { compressCSS: false, collapseWhitespace: false };
|
||||
controlArg(process.argv, 'share', function (arg, i) {
|
||||
share = true;
|
||||
|
||||
// because JS Bin is a damn sight easier to debug when it's not all on one line
|
||||
options.compressCSS = false;
|
||||
options.collapseWhitespace = false;
|
||||
});
|
||||
|
||||
controlArg(process.argv, 'images', function (arg, i) {
|
||||
options.images = false;
|
||||
});
|
||||
|
||||
// order counts here - so verbose can also use -v
|
||||
if (process.argv.length == 3) {
|
||||
controlArg(process.argv, 'version', function () {
|
||||
console.log(Inliner.prototype.version);
|
||||
process.exit();
|
||||
});
|
||||
}
|
||||
|
||||
controlArg(process.argv, 'verbose', function (arg, i) {
|
||||
process.argv.splice(i, 1);
|
||||
verbose = true;
|
||||
});
|
||||
|
||||
var inliner = new Inliner(process.argv[2], options, function (html) {
|
||||
console.log(html);
|
||||
if (process.argv[2] === undefined) {
|
||||
console.log(usage);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
var url = process.argv[2];
|
||||
if (url.indexOf('http') !== 0) {
|
||||
url = 'http://' + url;
|
||||
}
|
||||
|
||||
var inliner = new Inliner(url, options, function (html) {
|
||||
if (share) {
|
||||
// post to jsbin
|
||||
var data = querystring.stringify({
|
||||
html: html,
|
||||
javascript: '',
|
||||
format: 'plain',
|
||||
method: 'save'
|
||||
});
|
||||
|
||||
// note: when making a POST request using node, for PHP to pick it up, the content-type is crutial - I never knew that :(
|
||||
var request = Inliner.makeRequest('http://jsbin.com/save', {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/x-www-form-urlencoded', 'content-length': data.length, 'X-Requested-With' : 'XMLHttpRequest' }
|
||||
});
|
||||
request.on('response', function (res) {
|
||||
var body = '';
|
||||
res.on('data', function (chunk) {
|
||||
body += chunk;
|
||||
});
|
||||
res.on('end', function () {
|
||||
console.log(body);
|
||||
});
|
||||
});
|
||||
request.write(data);
|
||||
request.end();
|
||||
} else {
|
||||
console.log(html);
|
||||
}
|
||||
});
|
||||
|
||||
if (verbose) {
|
||||
|
59
inliner.js
59
inliner.js
@ -11,18 +11,6 @@ var URL = require('url'),
|
||||
https: require('https')
|
||||
};
|
||||
|
||||
function makeRequest(url) {
|
||||
var oURL = URL.parse(url),
|
||||
options = {
|
||||
host: oURL.hostname,
|
||||
port: oURL.port === undefined ? (oURL.protocol+'').indexOf('https') === 0 ? 443 : 80 : oURL.port,
|
||||
path: (oURL.pathname || '/') + (oURL.search || ''), // note 0.5.0pre doesn't fill pathname if missing
|
||||
method: 'GET'
|
||||
};
|
||||
|
||||
return http[oURL.protocol.slice(0, -1) || 'http'].request(options);
|
||||
}
|
||||
|
||||
function compressCSS(css) {
|
||||
return css
|
||||
.replace(/\s+/g, ' ')
|
||||
@ -56,9 +44,9 @@ function Inliner(url, options, callback) {
|
||||
|
||||
if (typeof options == 'function') {
|
||||
callback = options;
|
||||
options = inliner.defaults;
|
||||
options = Inliner.defaults;
|
||||
} else if (options === undefined) {
|
||||
options = inliner.defaults;
|
||||
options = Inliner.defaults;
|
||||
}
|
||||
|
||||
inliner.options = options;
|
||||
@ -84,8 +72,8 @@ function Inliner(url, options, callback) {
|
||||
], function(errors, window) {
|
||||
// remove jQuery that was included with jsdom
|
||||
window.$('script:last').remove();
|
||||
|
||||
var todo = { scripts: true, images: true, links: true, styles: true },
|
||||
|
||||
var todo = { scripts: true, images: inliner.options.images, links: true, styles: true },
|
||||
assets = {
|
||||
scripts: window.$('script'),
|
||||
images: window.$('img').filter(function(){ return this.src.indexOf('data:') == -1; }),
|
||||
@ -102,17 +90,19 @@ function Inliner(url, options, callback) {
|
||||
breakdown[key] = assets[key].length;
|
||||
inliner.total += assets[key].length;
|
||||
inliner.todo += assets[key].length;
|
||||
} else {
|
||||
assets[key] = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inliner.emit('jobs', (inliner.total - inliner.todo) + '/' + inliner.total);
|
||||
|
||||
function finished() {
|
||||
var items = 0;
|
||||
var items = 0,
|
||||
html = '';
|
||||
for (var key in breakdown) {
|
||||
items += breakdown[key];
|
||||
}
|
||||
|
||||
inliner.emit('jobs', (inliner.total - inliner.todo) + '/' + inliner.total);
|
||||
|
||||
if (items === 0) {
|
||||
@ -120,9 +110,14 @@ function Inliner(url, options, callback) {
|
||||
var els = removeComments(window.document.documentElement);
|
||||
|
||||
// collapse the white space
|
||||
var html = window.document.innerHTML;
|
||||
if (inliner.options.collapseWhitespace) {
|
||||
html = html.replace(/\s+/g, ' ');
|
||||
window.$('pre').html(function (i, html) {
|
||||
return html.replace(/\n/g, '~~nl~~').replace(/\s/g, '~~s~~');
|
||||
});
|
||||
html = window.document.innerHTML;
|
||||
html = html.replace(/\s+/g, ' ').replace(/~~nl~~/g, '\n').replace(/~~s~~/g, ' ');
|
||||
} else {
|
||||
html = window.document.innerHTML;
|
||||
}
|
||||
// console.log(html);
|
||||
html = '<!DOCTYPE html>' + html;
|
||||
@ -262,7 +257,7 @@ function Inliner(url, options, callback) {
|
||||
assets.scripts.length == 0) {
|
||||
finished();
|
||||
}
|
||||
|
||||
|
||||
/** Inliner jobs:
|
||||
* 1. get all inline images and base64 encode
|
||||
* 2. get all external style sheets and move to inline
|
||||
@ -331,7 +326,7 @@ Inliner.prototype.get = function (url, options, callback) {
|
||||
try {
|
||||
compress = require('./node-compress/lib/compress/');
|
||||
} catch (e) {
|
||||
console.error('Failed to load node-compress - see http://github.com/remy/inliner for install directions. \nexiting');
|
||||
console.error(url + ' sent gzipped header\nFailed to load node-compress - see http://github.com/remy/inliner for install directions. \nexiting');
|
||||
process.exit();
|
||||
}
|
||||
}
|
||||
@ -479,7 +474,23 @@ Inliner.prototype.getImportCSS = function (rooturl, css, callback) {
|
||||
}
|
||||
};
|
||||
|
||||
Inliner.prototype.defaults = { compressCSS: true, collapseWhitespace: true };
|
||||
Inliner.defaults = { compressCSS: true, collapseWhitespace: true, images: true };
|
||||
|
||||
var makeRequest = Inliner.makeRequest = function (url, extraOptions) {
|
||||
var oURL = URL.parse(url),
|
||||
options = {
|
||||
host: oURL.hostname,
|
||||
port: oURL.port === undefined ? (oURL.protocol+'').indexOf('https') === 0 ? 443 : 80 : oURL.port,
|
||||
path: (oURL.pathname || '/') + (oURL.search || ''), // note 0.5.0pre doesn't fill pathname if missing
|
||||
method: 'GET'
|
||||
};
|
||||
|
||||
for (var key in extraOptions) {
|
||||
options[key] = extraOptions[key];
|
||||
}
|
||||
|
||||
return http[oURL.protocol.slice(0, -1) || 'http'].request(options);
|
||||
};
|
||||
|
||||
module.exports = Inliner;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "inliner",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.3",
|
||||
"description": "Utility to inline images, CSS and JavaScript for a web page - useful for mobile sites",
|
||||
"homepage": "http://github.com/remy/inliner",
|
||||
"main": "inliner",
|
||||
|
Loading…
Reference in New Issue
Block a user