Refactored.

This commit is contained in:
Alexandre Gigliotti
2015-07-23 08:28:22 -07:00
parent e5e1f08fba
commit f4085786f6
13 changed files with 180 additions and 65 deletions

View File

@@ -1,68 +1,29 @@
var _ = require('lodash');
var co = require('co');
var inlineLess = require('inline-less');
var inlineCssUrl = require('inline-css-url');
var cheerio = require('cheerio');
var string = require('string');
var fs = require('mz/fs');
var inlineCss = require('./inline-css');
var inlineImg = require('./inline-img');
var inlineLinkLess = require('./inline-link-less');
// TODO refactor into separate module
// inline html images
var isLocalPath = require('is-local-path');
var datauri = require('datauri');
var path = require('path');
var inlineImg = function (html, filePath) {
var basedir = path.dirname(filePath);
var $ = cheerio.load(html);
var images = $('img').filter(function (index, element) {
return isLocalPath($(element).attr('src'));
var inline = co.wrap(function * (filename, options) {
options = _.defaults(options || {}, {
less: {}
});
images.each(function (index, element) {
var src = $(element).attr('src');
var filePath = path.resolve(basedir, src);
src = datauri(filePath);
$(element).attr('src', src);
});
return $.html();
};
var html = yield fs.readFile(filename, 'utf8');
// TODO refactor into separate module
// inline html url css data types
var inlineUrl = function (html, filePath) {
var $ = cheerio.load(html);
// style elements
var styles = $('style');
styles.each(function (index, element) {
var css = $(element).html();
css = inlineCssUrl(css, filePath);
$(element).html(css);
});
// style attributes
var attributes = $('body *').filter('[style]');
attributes.each(function (index, element) {
var css = $(element).attr('style');
var prefix = 'element {';
var suffix = '}';
css = prefix + css + suffix;
css = inlineCssUrl(css, filePath);
css = string(css).collapseWhitespace().toString();
css = css.replace(new RegExp('^' + prefix + '\\s*(.*)\\s+' + suffix + '$'), '$1');
$(element).attr('style', css);
});
return $.html();
};
var inline = co.wrap(function * (filePath, options) {
var html = yield fs.readFile(filePath, 'utf8');
// inline links: less
html = yield inlineLess(html, filePath, options);
// Inline links
html = yield inlineLinkLess(html, filename, options.less);
// TODO inline links: css
// TODO inline scripts (js + browserify? = scriptify)
// Inline local assets (path -> datauri)
html = inlineUrl(html, filePath);
html = inlineImg(html, filePath);
// svg?
// TODO inline scripts
// browserify js? => scriptify
// Inline paths -> datauris
html = inlineCss(html, filename);
html = inlineImg(html, filename);
return html;
});
module.exports = inline;

21
lib/inline-css-url.js Normal file
View File

@@ -0,0 +1,21 @@
var datauri = require('datauri');
var isLocalPath = require('is-local-path');
var path = require('path');
var rework = require('rework');
var url = require('rework-plugin-url');
var inline = function (css, filePath) {
var basePath = path.dirname(filePath);
css = rework(css)
.use(url(function (url) {
if (isLocalPath(url)) {
url = path.resolve(basePath, url);
url = datauri(url);
}
return url;
}))
.toString();
return css;
};
module.exports = inline;

39
lib/inline-css.js Normal file
View File

@@ -0,0 +1,39 @@
var cheerio = require('cheerio');
var inlineUrl = require('./inline-css-url');
var string = require('string');
var prefix = 'element {';
var suffix = '}';
var wrap = function (value) {
return prefix + value + suffix;
};
var unwrap = function (value) {
var regexp = new RegExp('^' + prefix + '\\s*(.*)\\s+' + suffix + '$');
return value.replace(regexp, '$1');
};
var inline = function (html, filePath) {
var $ = cheerio.load(html);
// style elements
var styles = $('style');
styles.each(function (index, element) {
var css = $(element).html();
css = inlineUrl(css, filePath);
$(element).html(css);
});
// style attributes
var attributes = $('body *').filter('[style]');
attributes.each(function (index, element) {
var css = $(element).attr('style');
css = wrap(css);
css = inlineUrl(css, filePath);
css = string(css).collapseWhitespace().toString();
css = unwrap(css);
$(element).attr('style', css);
});
return $.html();
};
module.exports = inline;

21
lib/inline-img.js Normal file
View File

@@ -0,0 +1,21 @@
var cheerio = require('cheerio');
var datauri = require('datauri');
var isLocalPath = require('is-local-path');
var path = require('path');
var inline = function (html, filePath) {
var basedir = path.dirname(filePath);
var $ = cheerio.load(html);
var images = $('img').filter(function (index, element) {
return isLocalPath($(element).attr('src'));
});
images.each(function (index, element) {
var src = $(element).attr('src');
var filePath = path.resolve(basedir, src);
src = datauri(filePath);
$(element).attr('src', src);
});
return $.html();
};
module.exports = inline;

58
lib/inline-link-less.js Normal file
View File

@@ -0,0 +1,58 @@
var _ = require('lodash');
var co = require('co');
var cheerio = require('cheerio');
var fs = require('mz/fs');
var isLocalPath = require('is-local-path');
var less = require('less');
var path = require('path');
var url = require('url');
var render = co.wrap(function * (filepath, options) {
options = _.assign(options || {}, {
filename: filepath
});
var contents = yield fs.readFile(filepath, 'utf8');
var output = yield less.render(contents, options);
return output.css;
});
/**
* @params html
* HTML to inline
* @params options
* LESS compiler options
*/
var inline = co.wrap(function * (html, filepath, options) {
var basedir = path.dirname(filepath);
options = _.defaults(options || {}, {
relativeUrls: true
});
// TODO Import less links
// get links
var $ = cheerio.load(html);
var links = $('link[rel="stylesheet/less"]')
.filter(function (index, element) {
return isLocalPath($(element).attr('href'));
});
// render stylesheets
var contents = [];
links.each(function (index, element) {
var href = $(element).attr('href');
var filepath = path.resolve(basedir, href);
contents.push(render(filepath, options));
});
contents = yield contents;
// TODO for each content: convert css url path -> datauri
// can use inline-css-url
// replace links
links.each(function (index, element) {
var style = $('<style>').html(contents[index]);
$(element).replaceWith(style);
});
return $.html();
});
module.exports = inline;

View File

@@ -12,10 +12,12 @@
"cheerio": "^0.19.0",
"co": "^4.6.0",
"datauri": "^0.7.1",
"inline-css-url": "file:../inline-css-url",
"inline-less": "file:../inline-less",
"is-local-path": "0.0.1",
"less": "^2.5.1",
"lodash": "^3.10.0",
"mz": "^2.0.0",
"rework": "^1.0.1",
"rework-plugin-url": "^1.0.1",
"string": "^3.3.0"
}
}

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@@ -1,13 +1,11 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet/less" href="main.less"/>
<style>
div {
padding-left: 2em;
}
</style>
<link rel="stylesheet/less" href="main.less"/>
<style>
#style {
background-image: url('./assets/person.png');
background-size: contain;

View File

@@ -2,11 +2,9 @@ var inline = require('../lib');
var path = require('path');
var fs = require('fs');
var filepath = path.resolve(__dirname, './index.html');
var filepath = path.resolve(__dirname, './fixtures/index.html');
var options = {};
/**
* html -> async -> inlined html
*/
inline(filepath, options)
.then(function (html) {
console.log(html);

7
test/inline-css-url.js Normal file
View File

@@ -0,0 +1,7 @@
var inline = require('../lib/inline-css-url');
var fs = require('fs');
var filePath = './fixtures/assets/imported.css';
var css = fs.readFileSync(filePath, 'utf8');
css = inline(css, filePath);
console.log(css);

10
test/inline-link-less.js Normal file
View File

@@ -0,0 +1,10 @@
var inline = require('../lib/inline-link-less');
var fs = require('fs');
var path = require('path');
var filepath = path.resolve(__dirname, './fixtures/index.html');
var html = fs.readFileSync(filepath, 'utf8');
inline(html, filepath, {})
.then(console.log)
.catch(console.error);