Skip to content

Commit 74c5516

Browse files
author
unknown
committed
Updating with asynchronous methods and callbacks
1 parent 57c74ea commit 74c5516

File tree

4 files changed

+157
-39
lines changed

4 files changed

+157
-39
lines changed

README.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,34 @@ A [NodeJS](http://nodejs.org/) package for inlining external stylesheets and emb
1212

1313
## Methods
1414

15-
### inlineHtml(html, options)
15+
### inlineHtml(html[, options], callback)
1616

1717
Inlines raw html content
1818

1919
- `html` - Raw html
2020
- `options` - See Options below
21+
- `callback` - Function
2122

22-
### inlineFile(inFile, outFile, options)
23+
inlineCSS.inlineHtml(html, function(inlineHtml) {
24+
console.log(inlineHtml);
25+
});
26+
27+
Returns `inlined html` as an argument.
28+
29+
### inlineFile(inFile, outFile[, options], callback)
2330

2431
Creates an inlined html file
2532

2633
- `inFile` - Location of file to be inlined
2734
- `outFile` - Destination of generated file
2835
- `options` - See Options below
36+
- `callback` - Function
37+
38+
inlineCSS.inlineFile(inFile, outFile, function() {
39+
console.log('success');
40+
});
41+
42+
No return arguments.
2943

3044
## Options
3145

index.js

Lines changed: 127 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,82 @@
11
var fs = require('fs'),
2+
path = require('path'),
23
cheerio = require('cheerio'),
34
parseCSS = require('css-rules');
45

5-
exports.inlineFile = function(inFile, outFile, options) {
6-
options = options || {};
7-
options.cssRoot = inFile.substring(0,Math.max(inFile.lastIndexOf("/"), inFile.lastIndexOf("\\"))+1);
6+
// EXPORTS: INLINE FILE
7+
exports.inlineFile = function(inFile, outFile, param1, param2) {
8+
var options = {},
9+
callback = null;
810

9-
var html = inline(fs.readFileSync(inFile, 'utf8'), options);
11+
if(param1) {
12+
if(typeof param1 === 'object')
13+
options = param1;
14+
else if(typeof param1 === 'function')
15+
callback = param1;
16+
}
17+
18+
if(param2) {
19+
if(typeof param2 === 'function' && callback === null) {
20+
callback = param2;
21+
} else {
22+
console.log('Error: Invalid param');
23+
return;
24+
}
25+
}
26+
27+
if(callback === null) {
28+
console.log('Error: No callback function specified');
29+
return;
30+
}
31+
32+
makeDirectoryRecursive(path.dirname(outFile), function() {
33+
options.cssRoot = inFile.substring(0,inFile.lastIndexOf(getPathSeparator(inFile))+1);
1034

11-
// Write to file
12-
fs.writeFileSync(outFile, html, 'utf8');
35+
fs.readFile(inFile, 'utf8', function(err, html) {
36+
inline(html, options, function(inlineHtml) {
37+
// Write to file
38+
fs.writeFile(outFile, inlineHtml, 'utf8', function() {
39+
callback();
40+
});
41+
});
42+
});
43+
});
1344
};
1445

15-
exports.inlineHtml = function(html, options) {
16-
options = options || {};
17-
return inline(html, options);
46+
// EXPORTS: INLINE HTML
47+
exports.inlineHtml = function(html, param1, param2) {
48+
var options = {},
49+
callback = null;
50+
51+
if(param1) {
52+
if(typeof param1 === 'object')
53+
options = param1;
54+
else if(typeof param1 === 'function')
55+
callback = param1;
56+
}
57+
58+
if(param2) {
59+
if(typeof param2 === 'function' && callback === null) {
60+
callback = param2;
61+
} else {
62+
console.log('Error: Invalid param');
63+
return;
64+
}
65+
}
66+
67+
if(callback === null) {
68+
console.log('Error: No callback function specified');
69+
return;
70+
}
71+
72+
inline(html, options, function(html) {
73+
callback(html);
74+
});
75+
1876
};
1977

20-
function inline(html, options) {
78+
// FUNCTION: inline
79+
function inline(html, options, callback) {
2180
var settings = {
2281
cssRoot: '',
2382
removeClasses: true
@@ -27,28 +86,72 @@ function inline(html, options) {
2786

2887
$ = cheerio.load(html);
2988

30-
// Loop through external stylesheets
89+
var stylesheets = [];
90+
3191
$('link').each(function(i, elem) {
3292
// Ignore remote files
33-
if(elem.attribs.href.substring(0, 4) != 'http' && elem.attribs.href.substring(0, 3) != 'ftp') {
34-
embedStyles(fs.readFileSync(settings.cssRoot + elem.attribs.href, 'utf8'));
93+
if(elem.attribs.href.substring(0, 4) != 'http' && elem.attribs.href.substring(0, 3) != 'ftp')
94+
stylesheets.push(settings.cssRoot + elem.attribs.href);
3595
$(this).remove();
36-
}
37-
});
38-
39-
// Loop through embedded style tags
40-
$('style').each(function(i, elem) {
41-
embedStyles($(this).text());
42-
$(this).remove();
4396
});
4497

45-
if(settings.removeClasses == true) {
46-
$('*').removeAttr('class');
98+
inlineStylesheetRecursive(stylesheets, function() {
99+
100+
// Loop through embedded style tags
101+
$('style').each(function(i, elem) {
102+
embedStyles($(this).text());
103+
$(this).remove();
104+
});
105+
106+
if(settings.removeClasses == true) {
107+
$('*').removeAttr('class');
108+
}
109+
110+
callback($.html());
111+
});
112+
}
113+
114+
// FUNCTION: inlineStylesheetRecursive
115+
// Loop through external stylesheets
116+
function inlineStylesheetRecursive(stylesheets, callback) {
117+
if(stylesheets.length > 0) {
118+
fs.readFile(stylesheets[0], 'utf8', function(err, css) {
119+
embedStyles(css);
120+
stylesheets.shift();
121+
inlineStylesheetRecursive(stylesheets, callback);
122+
});
123+
} else {
124+
callback();
47125
}
48-
49-
return $.html();
50126
}
51127

128+
// FUNCTION: makeDirectoryRecursive
129+
function makeDirectoryRecursive(dirPath, callback) {
130+
fs.exists(dirPath, function(exists) {
131+
if(!exists) {
132+
fs.mkdir(dirPath, function(err) {
133+
if (err && err.code == 'ENOENT') {
134+
makeDirectoryRecursive(path.dirname(dirPath));
135+
makeDirectoryRecursive(dirPath, callback);
136+
} else {
137+
if(callback) callback();
138+
}
139+
});
140+
} else {
141+
if(callback) callback();
142+
}
143+
});
144+
}
145+
146+
// FUNCTION: getPathSeparator
147+
function getPathSeparator(path) {
148+
if(path.indexOf('\\') > -1)
149+
return '\\';
150+
else
151+
return '/';
152+
};
153+
154+
// FUNCTION: embedStyles
52155
function embedStyles(css) {
53156
parseCSS(css).forEach(function (rule) {
54157
var selector = rule[0];

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "inlinecss",
3-
"version": "1.0.2",
3+
"version": "1.0.3",
44
"description": "Inlines stylesheets and style tags into html content",
55
"author": "Ripel Labs",
66
"main": "index.js",

test/test.js

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@ var inlineCSS = require('../index'),
22
fs = require('fs');
33

44
var inFile = 'test/html/in.html',
5-
outFile = 'test/html/out.html';
6-
7-
console.log('Test: Inlining file');
8-
console.log('----------------------------------');
9-
console.log('File: ' + inFile + '\n');
5+
outFile = 'test/html/content/generated/out.html';
106

11-
inlineCSS.inlineFile(inFile, outFile);
12-
console.log('Generated file `' + outFile + '`\n\n');
7+
inlineCSS.inlineFile(inFile, outFile, function() {
8+
console.log('Test: Inlining file');
9+
console.log('----------------------------------');
10+
console.log('File: ' + inFile + '\n');
11+
console.log('Generated file `' + outFile + '`\n\n');
12+
});
1313

1414
var html = '<style>\n\tp { height: 50px; } \n\t.info { font-weight: bold; }\n</style>\n<p class="info">This is a paragraph</p>';
1515

16-
console.log('Test: Inlining html' );
17-
console.log('----------------------------------');
18-
console.log('Html:\n' + html + '\n');
19-
html = inlineCSS.inlineHtml(html);
20-
console.log('Generated:' + html);
16+
inlineCSS.inlineHtml(html, function(inlineHtml) {
17+
console.log('Test: Inlining html' );
18+
console.log('----------------------------------');
19+
console.log('Html:\n' + html + '\n');
20+
console.log('Generated:' + inlineHtml + '\n\n');
21+
});

0 commit comments

Comments
 (0)