diff --git a/lib/index.js b/lib/index.js index dd522cd..59b12dd 100644 --- a/lib/index.js +++ b/lib/index.js @@ -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; diff --git a/lib/inline-css-url.js b/lib/inline-css-url.js new file mode 100644 index 0000000..c83b06c --- /dev/null +++ b/lib/inline-css-url.js @@ -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; diff --git a/lib/inline-css.js b/lib/inline-css.js new file mode 100644 index 0000000..c942279 --- /dev/null +++ b/lib/inline-css.js @@ -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; \ No newline at end of file diff --git a/lib/inline-img.js b/lib/inline-img.js new file mode 100644 index 0000000..a12df5d --- /dev/null +++ b/lib/inline-img.js @@ -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; diff --git a/lib/inline-link-less.js b/lib/inline-link-less.js new file mode 100644 index 0000000..2cca784 --- /dev/null +++ b/lib/inline-link-less.js @@ -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 = $(' - -