From f8369f3bc05351017b5d9e749968326f84130295 Mon Sep 17 00:00:00 2001 From: Alexandre Gigliotti Date: Wed, 22 Jul 2015 15:51:14 -0700 Subject: [PATCH] Initial commit. --- .gitignore | 2 ++ lib/index.js | 68 +++++++++++++++++++++++++++++++++++++++ package.json | 21 ++++++++++++ test/assets/imported.css | 8 +++++ test/assets/person.png | Bin 0 -> 5836 bytes test/index.html | 25 ++++++++++++++ test/index.js | 15 +++++++++ test/main.less | 7 ++++ 8 files changed, 146 insertions(+) create mode 100644 .gitignore create mode 100644 lib/index.js create mode 100644 package.json create mode 100644 test/assets/imported.css create mode 100644 test/assets/person.png create mode 100644 test/index.html create mode 100644 test/index.js create mode 100644 test/main.less diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..78ed38d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +test/test.html \ No newline at end of file diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..514aeea --- /dev/null +++ b/lib/index.js @@ -0,0 +1,68 @@ +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'); + +// TODO refactor into separate module +// inline html images +var localPath = require('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 localPath($(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(); +}; + +// 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); + // TODO inline links: css + // TODO inline scripts (js + browserify? = scriptify) + + // Inline local assets (path -> datauri) + html = inlineUrl(html, filePath); + html = inlineImg(html, filePath); + // svg? + + return html; +}); +module.exports = inline; diff --git a/package.json b/package.json new file mode 100644 index 0000000..f92653c --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "inline-html", + "version": "0.0.0", + "description": "", + "main": "lib/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "cheerio": "^0.19.0", + "co": "^4.6.0", + "datauri": "^0.7.1", + "inline-css-url": "file:../inline-css-url", + "inline-less": "file:../inline-less", + "local-path": "file:../local-path", + "mz": "^2.0.0", + "string": "^3.3.0" + } +} diff --git a/test/assets/imported.css b/test/assets/imported.css new file mode 100644 index 0000000..e9ad805 --- /dev/null +++ b/test/assets/imported.css @@ -0,0 +1,8 @@ +body { + border: solid 4px green; +} +#import { + background-image: url('./person.png'); + background-size: contain; + background-repeat: no-repeat; +} \ No newline at end of file diff --git a/test/assets/person.png b/test/assets/person.png new file mode 100644 index 0000000000000000000000000000000000000000..ad607a9a40757aa2e0ba75d08670031433e96511 GIT binary patch literal 5836 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 A7ytkO literal 0 HcmV?d00001 diff --git a/test/index.html b/test/index.html new file mode 100644 index 0000000..225a74b --- /dev/null +++ b/test/index.html @@ -0,0 +1,25 @@ + + + + + + + + + +
Import
+
Style
+
Attribute
+ Image + + \ No newline at end of file diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..e73e404 --- /dev/null +++ b/test/index.js @@ -0,0 +1,15 @@ +var inline = require('../lib'); +var path = require('path'); +var fs = require('fs'); + +var filepath = path.resolve(__dirname, './index.html'); +var options = {}; +/** + * html -> async -> inlined html + */ +inline(filepath, options) + .then(function (html) { + console.log(html); + fs.writeFileSync('./test.html', html); + }) + .catch(console.error); diff --git a/test/main.less b/test/main.less new file mode 100644 index 0000000..aead599 --- /dev/null +++ b/test/main.less @@ -0,0 +1,7 @@ +@import (less) './assets/imported.css'; + +#link { + background-image: url('assets/person.png'); + background-size: contain; + background-repeat: no-repeat; +} \ No newline at end of file