1
1
var fs = require ( 'fs' ) ,
2
+ path = require ( 'path' ) ,
2
3
cheerio = require ( 'cheerio' ) ,
3
4
parseCSS = require ( 'css-rules' ) ;
4
5
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 ;
8
10
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 ) ;
10
34
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
+ } ) ;
13
44
} ;
14
45
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
+
18
76
} ;
19
77
20
- function inline ( html , options ) {
78
+ // FUNCTION: inline
79
+ function inline ( html , options , callback ) {
21
80
var settings = {
22
81
cssRoot : '' ,
23
82
removeClasses : true
@@ -27,28 +86,72 @@ function inline(html, options) {
27
86
28
87
$ = cheerio . load ( html ) ;
29
88
30
- // Loop through external stylesheets
89
+ var stylesheets = [ ] ;
90
+
31
91
$ ( 'link' ) . each ( function ( i , elem ) {
32
92
// 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 ) ;
35
95
$ ( this ) . remove ( ) ;
36
- }
37
- } ) ;
38
-
39
- // Loop through embedded style tags
40
- $ ( 'style' ) . each ( function ( i , elem ) {
41
- embedStyles ( $ ( this ) . text ( ) ) ;
42
- $ ( this ) . remove ( ) ;
43
96
} ) ;
44
97
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 ( ) ;
47
125
}
48
-
49
- return $ . html ( ) ;
50
126
}
51
127
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
52
155
function embedStyles ( css ) {
53
156
parseCSS ( css ) . forEach ( function ( rule ) {
54
157
var selector = rule [ 0 ] ;
0 commit comments