Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

moved to commander for options and fixed up JS parsing errors

  • Loading branch information...
commit 229d4f146bee890d39667c81cc6510b43d11bed2 1 parent 8a5f50f
@remy authored
Showing with 99 additions and 100 deletions.
  1. +44 −64 bin/inliner
  2. +52 −34 inliner.js
  3. +3 −2 package.json
View
108 bin/inliner
@@ -1,90 +1,70 @@
#!/usr/bin/env node
-var path = require('path'), fs = require('fs'), querystring = require('querystring'), util = require('util');
+var path = require('path'),
+ fs = require('fs'),
+ querystring = require('querystring'),
+ util = require('util');
fs.realpath(__filename, function(error, script) {
var servedir, root, port;
if (error) throw error;
- // Load `servedir`.
var Inliner = require(path.join(path.dirname(script), '../inliner')),
- usage = [
- 'usage: inliner [options] http://yoursite.com',
- 'e.g.: inliner http://localhost:8080',
- '',
- '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');
-
- 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) {
- callback(args[i], i);
- } else if ((i = args.indexOf('-' + label.substr(0, 1))) !== -1) {
- callback(args[i], i);
- } else if ((i = args.indexOf('--' + label)) !== -1) {
- callback(args[i], i);
- }
- }
+ program = require('commander');
+
+ program
+ .version(Inliner.version)
+ .usage('[options] http://yoursite.com')
+ .option('-v, --verbose', 'echo on STDERR the progress of inlining')
+ .option('-n, --nocompress', "don't compress CSS or HTML - useful for debugging")
+ .option('-i, --images', "don't encode images - keeps files size small, but more requests")
+ //.option('-s, --share', "create jsbin.com url for HTML page")
+ //.option('-h, --help', "help - you're looking at it");
+
+ program.on('--help', function () {
+ console.log(' Examples:');
+ console.log('');
+ console.log(' $ inliner -v http://twitter.com > twitter.html');
+ console.log(' $ inliner -ni http://twitter.com > twitter.html');
+ console.log('');
+ console.log(' For more details see http://github.com/remy/inliner/');
+ console.log('');
+ });
+
+ program.parse(process.argv);
var options = Inliner.defaults(),
verbose = false,
share = false;
- controlArg(process.argv, 'help', function () {
- console.log(usage);
- process.exit();
- });
-
- controlArg(process.argv, 'nocompress', function (arg, i) {
+ if (program.nocompress) {
options.compressCSS = false;
options.collapseWhitespace = false;
- });
+ }
- controlArg(process.argv, 'share', function (arg, i) {
+ if (program.share) {
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) {
- verbose = true;
- });
+ options.images = !program.images;
+ verbose = program.verbose;
- if (process.argv[2] === undefined) {
- console.log(usage);
- process.exit();
+ if (program.args.length == 0) {
+ // ripped out of commander.js - should really be process.usage()
+ process.stdout.write(program.helpInformation());
+ program.emit('--help');
+ process.exit(0);
}
- var url = process.argv[2];
- if (url.indexOf('http') !== 0) {
+ var url = program.args[0];
+
+ if (path.existsSync(url)) {
+ // then it's a file
+ } else if (url.indexOf('http') !== 0) {
url = 'http://' + url;
}
@@ -113,10 +93,10 @@ fs.realpath(__filename, function(error, script) {
});
});
request.write(data);
- request.end();
+ request.end();
} else {
// using util.print because console.log evalutes sprintf commands - which we don't want to do
- util.print(html);
+ util.print(html);
}
});
View
86 inliner.js
@@ -1,10 +1,14 @@
var URL = require('url'),
util = require('util'),
+ jsmin = require('./jsmin'),
events = require('events'),
Buffer = require('buffer').Buffer,
+ fs = require('fs'),
+ path = require('path'),
jsdom = require('jsdom'),
- jsp = require('uglify-js/lib/parse-js'),
- pro = require('uglify-js/lib/process'),
+ uglifyjs = require('uglify-js'),
+ jsp = uglifyjs.parser,
+ pro = uglifyjs.uglify,
compress = null, // import only when required - might make the command line tool easier to use
http = {
http: require('http'),
@@ -111,11 +115,14 @@ function Inliner(url, options, callback) {
if (items === 0) {
// manually remove the comments
var els = removeComments(window.document.documentElement);
-
// collapse the white space
if (inliner.options.collapseWhitespace) {
+ // TODO put white space helper back in
window.$('pre').html(function (i, html) {
- return html.replace(/\n/g, '~~nl~~').replace(/\s/g, '~~s~~');
+ return html.replace(/\n/g, '~~nl~~'); //.replace(/\s/g, '~~s~~');
+ });
+ window.$('textarea').val(function (i, v) {
+ return v.replace(/\n/g, '~~nl~~').replace(/\s/g, '~~s~~');
});
html = window.document.innerHTML;
html = html.replace(/\s+/g, ' ').replace(/~~nl~~/g, '\n').replace(/~~s~~/g, ' ');
@@ -179,7 +186,7 @@ function Inliner(url, options, callback) {
}
window.$(link).replaceWith(style);
- finished();
+ finished();
});
});
});
@@ -192,7 +199,10 @@ function Inliner(url, options, callback) {
assets.scripts.each(function () {
var $script = window.$(this),
src = $script.attr('src'),
- orig_code = this.innerHTML,
+ // note: not using .innerHTML as this coerses & => &
+ orig_code = this.firstChild.nodeValue
+ .replace(/<\/script>/gi, '<\\/script>'),
+ // .replace(/\/\/.*\n/gi, ''),
final_code = '';
// only remove the src if we have a script body
@@ -213,26 +223,25 @@ function Inliner(url, options, callback) {
final_code = pro.gen_code(ast);
// some protection against putting script tags in the body
- final_code = final_code.replace(/<\/script>/gi, '<\\/script>');
-
- this.innerText = final_code;
- // window.$(this).text(final_code);
+ window.$(this).text(final_code).append('\n');
if (src) {
inliner.emit('progress', 'compress ' + URL.resolve(root, src));
} else {
inliner.emit('progress', 'compress inline script');
- }
+ }
} catch (e) {
// console.error(orig_code.indexOf('script>script'));
- // this.innerHTML = orig_code.replace(/<\/script>/gi, '<\\/script>');
- // console.error('exception', e);
+ // window.$(this).html(jsmin('', orig_code, 2));
+ console.error('exception on ', src);
+ console.error('exception in ' + src + ': ' + e.message);
+ console.error('>>>>>> ' + orig_code.split('\n')[e.line - 1]);
}
inliner.todo--;
inliner.emit('jobs', (inliner.total - inliner.todo) + '/' + inliner.total);
} else if (orig_code) {
- // window.$(this).text(orig_code.replace(/<\/script>/gi, '<\\/script>'));
- this.innerText = orig_code.replace(/<\/script>/gi, '<\\/script>');
+ window.$(this).text(orig_code);
+ // this.innerText = orig_code;
}
});
finished();
@@ -252,7 +261,7 @@ function Inliner(url, options, callback) {
} else if (this.src) {
inliner.get(scriptURL, { not: 'text/html' }, function (data) {
// catches an exception that was being thrown, but script escaping wasn't being caught
- if (data) $script.text(data.replace(/<\/script>/gi, '<\\/script>'));
+ if (data) $script.text(data.replace(/<\/script>/gi, '<\\/script>')); //.replace(/\/\/.*$\n/g, ''));
// $script.before('<!-- ' + scriptURL + ' -->');
breakdown.scripts--;
inliner.todo--;
@@ -289,7 +298,7 @@ function Inliner(url, options, callback) {
util.inherits(Inliner, events.EventEmitter);
-Inliner.prototype.version = JSON.parse(require('fs').readFileSync(__dirname + '/package.json').toString()).version;
+Inliner.version = Inliner.prototype.version = JSON.parse(require('fs').readFileSync(__dirname + '/package.json').toString()).version;
Inliner.prototype.get = function (url, options, callback) {
// support no options being passed in
@@ -308,11 +317,30 @@ Inliner.prototype.get = function (url, options, callback) {
} else {
this.requestCachePending[url] = [callback];
}
+
+ var inliner = this;
+
+ // TODO remove the sync
+ if (path.existsSync(url)) {
+ // then we're dealing with a file
+ fs.readFile(url, 'utf8', function (err, body) {
+ inliner.requestCache[url] = body;
+ inliner.requestCachePending[url].forEach(function (callback, i) {
+ if (i == 0 && body) {
+ inliner.emit('progress', (options.encode ? 'encode' : 'get') + ' ' + url);
+ } else if (body) {
+ inliner.emit('progress', 'cached ' + url);
+ }
+ callback && callback(body);
+ });
+ });
+
+ return;
+ }
// otherwis continue and create a new web request
var request = makeRequest(url),
- body = '',
- inliner = this;
+ body = '';
// this tends to occur when we can't connect to the url - i.e. target is down
// note that the main inliner app handles sending the error back to the client
@@ -330,6 +358,7 @@ Inliner.prototype.get = function (url, options, callback) {
// once loaded, we set up event listeners to handle data coming in and do a little
// dance with the response object - which I'll explain... ==>
if (res.headers['content-encoding'] == 'gzip') {
+ console.error('loading gzip library');
if (compress === null) {
try {
compress = require('./node-compress/lib/compress/');
@@ -374,6 +403,7 @@ Inliner.prototype.get = function (url, options, callback) {
gunzip.end();
return;
}
+
if (res.statusCode !== 200) {
inliner.emit('progress', 'get ' + res.statusCode + ' on ' + url);
body = ''; // ?
@@ -508,19 +538,7 @@ var makeRequest = Inliner.makeRequest = function (url, extraOptions) {
module.exports = Inliner;
if (!module.parent) {
- if (process.argv[2] === undefined) {
- console.log('Usage: inliner http://yoursite.com\ninliner [nocompress]\nThis will output the inlined HTML, CSS, images and JavaScript');
- process.exit();
- }
-
- (function () {
- var options;
- if (process.argv[3] === 'nocompress') {
- options = { compressCSS: false, collapseWhitespace: false };
- }
-
- var inliner = new Inliner(process.argv[2], options, function (html) {
- require('util').print(html);
- });
- })();
+ // if this module isn't being included in a larger app, defer to the
+ // bin/inliner for the help options
+ require('./bin/inliner');
}
View
5 package.json
@@ -10,8 +10,9 @@
"web": "http://github.com/remy"
},
"dependencies": {
- "jsdom": ">=0.2.0",
- "uglify-js": ">=1.0.2"
+ "jsdom": "latest",
+ "uglify-js": "1.2.2",
+ "commander": "0.5.1"
},
"repository": {
"type": "git",
Please sign in to comment.
Something went wrong with that request. Please try again.