diff --git a/README.md b/README.md index 23fb6ce..665cae1 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ To create the following `html` string: --- -### inlineHtml ( filename [, options] ) +### inlineHtml ( html [, options] ) Reads an HTML file and embeds referenced local assets into the HTML. @@ -89,8 +89,9 @@ Returns a `Promise` that is fulfilled with an `html` string or an instance of [` __Arguments__ -- `filename` - The filename of the HTML file to be inlined. Relative file paths are resolved relative to the filename directory. +- `html` - An HTML string or a filename of an HTML file to inline. Relative file paths are resolved relative to `options.filename` if a string or the filename's directory if a filename. - `options` + - `filename` - The filename used to resolve relative paths when `html` is a string. If `html` is a string and this option is not provided, relative paths will be resolved relative to the process's current working directory. - `less` - An object containing LESS options to pass to the less compiler. Defaults to `{}`. - `verbose` - A boolean that determines the promises fulfillment value. Supported values are: - `true`: An instance of [`Results`](#Results). diff --git a/lib/index.js b/lib/index.js index 3245be5..dfbf9d1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -6,12 +6,25 @@ var inlineStyle = require('./inline-style'); var inlineImg = require('./inline-img'); var inlineLinkLess = require('./inline-link-less'); -var inline = co.wrap(function * (filename, options) { +var inline = co.wrap(function * (html, options) { options = _.defaults(options || {}, { + filename: null, less: {}, verbose: false }); - var html = yield fs.readFile(filename, 'utf8'); + var filename; + try { + filename = html; + html = yield fs.readFile(filename, 'utf8'); + } + catch (error) { + if (error.code === 'ENOENT') { + filename = options.filename; + } + else { + throw error; + } + } var files = [filename]; // Inline links diff --git a/package.json b/package.json index 33b3d42..1a192d5 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "repository": "panosoft/inline-html", "main": "lib/index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "mocha --harmony_arrow_functions" }, "author": "", "license": "MIT", @@ -17,8 +17,13 @@ "less": "^2.5.1", "lodash": "^3.10.0", "mz": "^2.0.0", - "postcss": "^4.1.16", + "postcss": "^5.0.0", "postcss-url": "^4.0.0", "string": "^3.3.0" + }, + "devDependencies": { + "chai": "^3.2.0", + "chai-as-promised": "^5.1.0", + "mocha": "^2.2.5" } } diff --git a/test/fixtures/assets/imported.css b/test/fixtures/assets/imported.css deleted file mode 100644 index e9ad805..0000000 --- a/test/fixtures/assets/imported.css +++ /dev/null @@ -1,8 +0,0 @@ -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/fixtures/assets/person.png b/test/fixtures/assets/person.png deleted file mode 100644 index ad607a9..0000000 Binary files a/test/fixtures/assets/person.png and /dev/null differ diff --git a/test/fixtures/basic.css b/test/fixtures/basic.css new file mode 100644 index 0000000..76ed3ff --- /dev/null +++ b/test/fixtures/basic.css @@ -0,0 +1 @@ +div { color: blue; } diff --git a/test/fixtures/basic.less b/test/fixtures/basic.less new file mode 100644 index 0000000..76ed3ff --- /dev/null +++ b/test/fixtures/basic.less @@ -0,0 +1 @@ +div { color: blue; } diff --git a/test/fixtures/css-url.html b/test/fixtures/css-url.html new file mode 100644 index 0000000..1c35656 --- /dev/null +++ b/test/fixtures/css-url.html @@ -0,0 +1 @@ + diff --git a/test/fixtures/file.txt b/test/fixtures/file.txt new file mode 100644 index 0000000..90b67dd --- /dev/null +++ b/test/fixtures/file.txt @@ -0,0 +1 @@ +Test. diff --git a/test/fixtures/img.html b/test/fixtures/img.html new file mode 100644 index 0000000..e5b058f --- /dev/null +++ b/test/fixtures/img.html @@ -0,0 +1 @@ + diff --git a/test/fixtures/import.less b/test/fixtures/import.less new file mode 100644 index 0000000..d120e67 --- /dev/null +++ b/test/fixtures/import.less @@ -0,0 +1,2 @@ +@import 'basic.less'; +@import (inline) 'basic.css'; diff --git a/test/fixtures/index.html b/test/fixtures/index.html deleted file mode 100644 index b967eaa..0000000 --- a/test/fixtures/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - -
Import
-
Style
-
Attribute
- Image - {{> partial}} - {{helper}} - - \ No newline at end of file diff --git a/test/fixtures/main.less b/test/fixtures/main.less deleted file mode 100644 index aead599..0000000 --- a/test/fixtures/main.less +++ /dev/null @@ -1,7 +0,0 @@ -@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 diff --git a/test/index.js b/test/index.js index 6f5fcb8..5ed8472 100644 --- a/test/index.js +++ b/test/index.js @@ -1,13 +1,163 @@ var inline = require('../lib'); -var path = require('path'); +var expect = require('chai') + .use(require('chai-as-promised')) + .expect; +var datauri = require('datauri'); var fs = require('fs'); +var path = require('path'); -var filepath = path.resolve(__dirname, './fixtures/index.html'); -var options = {verbose: true}; +describe('inlineHtml', function () { -inline(filepath, options) - .then(function (html) { - console.log(html); - fs.writeFileSync('./test.html', html); - }) - .catch(console.error); + it('html: filename', function () { + var filename = path.resolve(__dirname, './fixtures/file.txt'); + var content = fs.readFileSync(filename, 'utf8'); + return expect(inline(filename)).to.eventually.equal(content); + }); + it('html: string', function () { + var html = 'HTML'; + return expect(inline(html)).to.eventually.equal(html); + }); + + + it('inline link less', function () { + var filename = path.resolve(__dirname, 'fixtures/basic.less'); + var html = ``; + return expect(inline(html)).to.eventually.match(/`; + return expect(inline(html)).to.eventually.match(/data:.*,.*/); + }); + it('inline css url path in element style attribute', function () { + var filename = path.resolve(__dirname, 'fixtures/file.txt'); + var html = `
`; + return expect(inline(html)).to.eventually.match(/data:.*,.*/); + }); + it('inline img src', function () { + var filename = path.resolve(__dirname, 'fixtures/file.txt'); + var html = ``; + return expect(inline(html)).to.eventually.match(/data:.*,.*/); + }); + + + it('options.verbose: return results object if true', function () { + var filename = path.resolve(__dirname, 'fixtures/file.txt'); + var html = ``; + var options = { verbose: true }; + return expect(inline(html, options)).to.eventually.be.an('object') + .that.contains.keys(['html', 'files']); + }); + it('options.verbose: return html if false', function () { + var filename = path.resolve(__dirname, 'fixtures/file.txt'); + var html = ``; + var options = { verbose: false }; + return expect(inline(html, options)).to.eventually.be.a('string'); + }); + it('options.verbose: default false', function () { + var filename = path.resolve(__dirname, 'fixtures/file.txt'); + var html = ``; + return expect(inline(html)).to.eventually.be.a('string'); + }); + + + it('options.filename: ignored for css url path resolution if html filename', function () { + var html = path.resolve(__dirname, 'fixtures/css-url.html'); // file contains url path relative to itself + var options = { filename: __filename }; // sets filename relative to this test file + return expect(inline(html, options)).to.eventually.match(/"data:.*,.*"/); + }); + it('options.filename: ignored for img src path resolution if html filename', function () { + var html = path.resolve(__dirname, 'fixtures/img.html'); // file contains src relative to itself + var options = { filename: __filename }; // sets filename relative to this test file + return expect(inline(html, options)).to.eventually.match(/"data:.*,.*"/); + }); + it('options.filename: set basepath for css url path resolution if html string', function () { + var filename = path.resolve(__dirname, 'fixtures/fake.html'); + var dirname = path.dirname(filename); + + var url = 'file.txt'; // Note: path relative to filename's dirname + var uri = datauri(path.resolve(dirname, url)); + + var html = (path) => ``; + var options = { filename: filename }; + return expect(inline(html(url), options)).to.eventually.equal(html(uri)); + }); + it('options.filename: set basepath for img src path resolution if html string', function () { + var filename = path.resolve(__dirname, 'fixtures/fake.html'); + var dirname = path.dirname(filename); + + var url = 'file.txt'; // Note: path relative to filename's dirname + var uri = datauri(path.resolve(dirname, url)); + + var html = (path) => ``; + var options = { filename: filename }; + return expect(inline(html(url), options)).to.eventually.equal(html(uri)); + }); + it('options.filename: default to cwd for css url path resolution if html string', function () { + var url = 'test/fixtures/file.txt'; // Note: this is relative to cwd + var uri = datauri(url); + + var html = (path) => ``; + return expect(inline(html(url))).to.eventually.equal(html(uri)); + }); + it('options.filename: default to cwd for img src path resolution if html string', function () { + var url = 'test/fixtures/file.txt'; // Note: path relative to cwd + var uri = datauri(url); + + var html = (path) => ``; + return expect(inline(html(url))).to.eventually.equal(html(uri)); + }); + it('options.filename: included in results.files for img src if html string and options.verbose true', function () { + var filename = path.resolve(__dirname, 'fixtures/file.txt'); + var html = ``; + var options = { verbose: true }; + return expect(inline(html, options)).to.eventually.have.property('files') + .that.is.an('array') + .that.contains(filename); + }); + it('options.filename: included in results.files for css url path if html string and options.verbose true', function () { + var filename = path.resolve(__dirname, 'fixtures/file.txt'); + var html = ``; + var options = { verbose: true }; + return expect(inline(html, options)).to.eventually.have.property('files') + .that.is.an('array') + .that.contains(filename); + }); + + + it('preserve self closing tags', function () { + var html = '
'; + return expect(inline(html)).to.eventually.equal(html); + }); + it('preserve partials', function () { + var html = '{{> partial}}'; + return expect(inline(html)).to.eventually.equal(html); + }); + it('preserve helpers', function () { + var html = '{{helper}}'; + return expect(inline(html)).to.eventually.equal(html); + }); + + it('ignore css url remote paths', function () { + var html = ``; + return expect(inline(html)).to.eventually.equal(html); + }); + it('ignore img src remote paths', function () { + var html = ``; + return expect(inline(html)).to.eventually.equal(html); + }); + it('ignore query strings and hashes on local paths', function () { + var filename = path.resolve(__dirname, 'fixtures/file.txt'); + var url = `${filename}?query=string#hash`; + var uri = datauri(filename); + var html = (source) => ``; + return expect(inline(html(url))).to.eventually.equal(html(uri)); + }); + +}); diff --git a/test/inline-css-url.js b/test/inline-css-url.js deleted file mode 100644 index 0fbed5e..0000000 --- a/test/inline-css-url.js +++ /dev/null @@ -1,7 +0,0 @@ -var inline = require('../lib/inline-css-url'); -var fs = require('fs'); - -var filePath = './fixtures/assets/imported.css'; -var css = fs.readFileSync(filePath, 'utf8'); -var result = inline(css, filePath); -console.log(result.css); diff --git a/test/inline-link-less.js b/test/inline-link-less.js deleted file mode 100644 index 280568d..0000000 --- a/test/inline-link-less.js +++ /dev/null @@ -1,10 +0,0 @@ -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);