├── .gitignore
├── test
├── testfiles
│ ├── 08-expected.html
│ ├── 09-expected.html
│ ├── 18-expected.html
│ ├── 19-expected.html
│ ├── 25-expected.html
│ ├── tmp
│ │ └── out.html
│ ├── 01-expected.html
│ ├── 08.html
│ ├── 10-expected.html
│ ├── 15-expected.html
│ ├── 20-expected.html
│ ├── 24.html
│ ├── 02-expected.html
│ ├── 12-expected.html
│ ├── 21-expected.html
│ ├── 22-expected.html
│ ├── 03-expected.html
│ ├── 16-expected.html
│ ├── 13-expected.html
│ ├── 16-win-expected.html
│ ├── 14-expected.html
│ ├── 17-expected.html
│ ├── 22.html
│ ├── 23.html
│ ├── 25.html
│ ├── 19.html
│ ├── 18.html
│ ├── 01.html
│ ├── 17.html
│ ├── 05.html
│ ├── 20.html
│ ├── 09.html
│ ├── 21.html
│ ├── 15.html
│ ├── 02.html
│ ├── 12.html
│ ├── 06.html
│ ├── 03d.html
│ ├── 03e.html
│ ├── 03f.html
│ ├── 13.html
│ ├── 16.html
│ ├── 14.html
│ ├── 03c.html
│ ├── 16-win.html
│ ├── 26-expected.jade
│ ├── 03.html
│ ├── 03b.html
│ ├── 04-expected.html
│ ├── 10.html
│ ├── 26.jade
│ ├── 07.html
│ └── 04.html
└── test.js
├── package.json
├── LICENSE
├── README.md
└── src
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/test/testfiles/08-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/test/testfiles/09-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/testfiles/18-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/test/testfiles/19-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/test/testfiles/25-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | target
5 |
6 | target
7 |
8 |
--------------------------------------------------------------------------------
/test/testfiles/tmp/out.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/test/testfiles/01-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/test/testfiles/08.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/testfiles/10-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | keepthis
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/testfiles/15-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/test/testfiles/20-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/test/testfiles/24.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/test/testfiles/02-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/testfiles/12-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/testfiles/21-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/testfiles/22-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/testfiles/03-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/test/testfiles/16-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
--------------------------------------------------------------------------------
/test/testfiles/13-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/testfiles/16-win-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
--------------------------------------------------------------------------------
/test/testfiles/14-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/testfiles/17-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/test/testfiles/22.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/testfiles/23.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/testfiles/25.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/testfiles/19.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/test/testfiles/18.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/test/testfiles/01.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/testfiles/17.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/testfiles/05.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/testfiles/20.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/test/testfiles/09.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/testfiles/21.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/testfiles/15.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/testfiles/02.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/testfiles/12.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/testfiles/06.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/testfiles/03d.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/testfiles/03e.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/testfiles/03f.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/testfiles/13.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/testfiles/16.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/testfiles/14.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/testfiles/03c.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/testfiles/16-win.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/testfiles/26-expected.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html(lang='en')
3 | head
4 |
5 |
6 |
7 |
8 | body
9 | block content
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/test/testfiles/03.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/testfiles/03b.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/testfiles/04-expected.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/test/testfiles/10.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | keepthis
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/test/testfiles/26.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html(lang='en')
3 | head
4 |
5 | //- build:css({.tmp/serve,src}) /styles/vendor.css -->
6 | link(rel='stylesheet', href='/bower_components/some_module/main.css')
7 | //- endbuild -->
8 |
9 |
10 | body
11 | block content
12 |
13 | //- build:js({.tmp/serve,src}) /scripts/vendor.js -->
14 | script(type='text/javascript', src='/bower_components/jquery/dist/jquery.js')
15 | //- endbuild -->
16 |
17 | //- build:js({src,.tmp/serve}) /scripts/app.js -->
18 | script(type='text/javascript', src='/config.js')
19 | //- endbuild -->
20 |
--------------------------------------------------------------------------------
/test/testfiles/07.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-useref",
3 | "version": "0.3.15",
4 | "description": "Parse build blocks in HTML files to replace references",
5 | "main": "src/index.js",
6 | "directories": {
7 | "test": "test"
8 | },
9 | "scripts": {
10 | "test": "mocha test"
11 | },
12 | "keywords": [
13 | "build",
14 | "blocks",
15 | "build",
16 | "comments",
17 | "replace",
18 | "scripts",
19 | "link",
20 | "ref"
21 | ],
22 | "author": "Manuel Cabral (m.cabral@digisfera.pt)",
23 | "license": "MIT",
24 | "dependencies": {},
25 | "devDependencies": {
26 | "chai": "~1.8.1",
27 | "mocha": "~1.17.0"
28 | },
29 | "repository": {
30 | "type": "git",
31 | "url": "git://github.com/manuelcabral/useref.git"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/test/testfiles/04.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Digisfera
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # useref
2 |
3 | **This project is no longer maintained. Please see [this fork](https://github.com/jonkemp/useref).**
4 |
5 | Parse build blocks in HTML files to replace references.
6 |
7 | Extracted from the grunt plugin [grunt-useref](https://github.com/pajtai/grunt-useref).
8 |
9 | ## Installation
10 |
11 | ```
12 | npm install node-useref
13 | ```
14 |
15 | ## Usage
16 |
17 | ```js
18 | useref = require('node-useref')
19 | var result = useref(inputHtml)
20 | // result = [ replacedHtml, { type: { path: { 'assets': [ replacedFiles] }}} ]
21 | ```
22 |
23 |
24 | Blocks are expressed as:
25 |
26 | ```html
27 |
28 | ... HTML Markup, list of script / link tags.
29 |
30 | ```
31 |
32 | - **type**: either `js`, `css` or `remove`
33 | - **alternate search path**: (optional) By default the input files are relative to the treated file. Alternate search path allows one to change that
34 | - **path**: the file path of the optimized file, the target output
35 | - **parameters**: extra parameters that should be added to the tag
36 |
37 | An example of this in completed form can be seen below:
38 |
39 | ```html
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | ```
60 |
61 | The module would be used with the above sample HTML as follows:
62 |
63 | ```js
64 | var result = useref(sampleHtml)
65 |
66 | // [
67 | // resultHtml,
68 | // {
69 | // css: {
70 | // 'css/combined.css': {
71 | // 'assets': [ 'css/one.css', 'css/two.css' ]
72 | // }
73 | // },
74 | // js: {
75 | // 'scripts/combined.js': {
76 | // 'assets': [ 'scripts/one.js', 'scripts/two.js' ]
77 | // },
78 | // 'scripts/async.js': {
79 | // 'assets': [ 'scripts/three.js', 'scripts/four.js' ]
80 | // }
81 | // }
82 | // }
83 | // ]
84 | ```
85 |
86 |
87 | The resulting HTML would be:
88 |
89 | ```html
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | ```
100 |
101 | ## IE Conditional Comments
102 |
103 | Internet Explorer Conditional Comments are preserved. The code below:
104 |
105 | ```html
106 |
107 |
111 |
112 | ```
113 |
114 | Results in:
115 |
116 | ```html
117 |
120 | ```
121 |
122 | ### Custom blocks
123 |
124 | Sometimes you need a bit more. If you would like to do custom processing, this is possible with a custom block, as demonstrated below.
125 |
126 | ```
127 |
128 |
129 |
130 | ```
131 |
132 | With
133 |
134 | ```
135 | useref = require('node-useref')
136 | var result = useref(inputHtml, {
137 | // each property corresponds to any blocks with the same name, e.g. "build:import"
138 | import: function (content, target, options, alternateSearchPath) {
139 | // do something with `content` and return the desired HTML to replace the block content
140 | return content.replace('bower_components', target);
141 | }
142 | });
143 | ```
144 |
145 | Becomes
146 |
147 | ```
148 |
149 | ```
150 |
151 | The handler function gets the following arguments:
152 |
153 | - *content* (String): The content of the custom use block
154 | - *target* (String): The "path" value of the use block definition
155 | - *options* (String): The extra attributes from the use block definition, the developer can parse as JSON or do whatever they want with it
156 | - *alternateSearchPath* (String): The alternate search path that can be used to maintain a coherent interface with standard handlers
157 |
158 | Include a handler for each custom block type.
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | /*global module:false, require:false */
2 | 'use strict';
3 |
4 | // start build pattern:
5 | // $1 is the type, $2 is the alternate search path, $3 is the destination file name $4 extra attributes
6 | var regbuild = /(?:)|[^\s]+)?\s*(?:(.*))?\s*-->/;
7 |
8 | // end build pattern --
9 | var regend = /(?:/;
10 |
11 | // IE conditional comment pattern: $1 is the start tag and $2 is the end tag
12 | var regcc = /()/i;
13 |
14 | // script element regular expression
15 | // TODO: Detect 'src' attribute.
16 | var regscript = /|\))<[^<]*)*(?:<\/script>|\))/gmi;
17 |
18 | // css link element regular expression
19 | // TODO: Determine if 'href' attribute is present.
20 | var regcss = /|\))/gmi;
21 |
22 | // Character used to create key for the `sections` object. This should probably be done more elegantly.
23 | var sectionsJoinChar = '\ue000';
24 |
25 | // strip all comments from HTML except for conditionals
26 | var regComment = /)(.|\n))*-->/g;
27 |
28 | module.exports = function (content, options) {
29 | var blocks = getBlocks(content);
30 |
31 | content = updateReferences(blocks, content, options);
32 |
33 | var replaced = compactContent(blocks);
34 |
35 | return [ content, replaced ];
36 | };
37 |
38 | function parseBuildBlock(block) {
39 | var parts = block.match(regbuild);
40 | return parts && {
41 | type: parts[1],
42 | alternateSearchPaths: parts[2],
43 | target: parts[3] && parts[3].trim(),
44 | attbs: parts[4] && parts[4].trim()
45 | }
46 | }
47 |
48 | // Returns a hash object of all the directives for the given html. Results is
49 | // of the following form:
50 | //
51 | // {
52 | // 'css/site.css ':[
53 | // ' ',
54 | // ' ',
55 | // ' '
56 | // ],
57 | // 'js/head.js ': [
58 | // ' ',
59 | // ' ',
60 | // ' '
61 | // ],
62 | // 'js/site.js ': [
63 | // ' ',
64 | // ' ',
65 | // ' ',
66 | // ' '
67 | // ]
68 | // }
69 | //
70 | function getBlocks(body) {
71 | var lines = body.replace(/\r\n/g, '\n').split(/\n/),
72 | block = false,
73 | sections = {},
74 | sectionIndex = 0,
75 | last,
76 | removeBlockIndex = 0;
77 |
78 | lines.forEach(function (l) {
79 | var build = parseBuildBlock(l),
80 | endbuild = regend.test(l),
81 | sectionKey;
82 |
83 | if (build) {
84 | block = true;
85 |
86 | if(build.type === 'remove') { build.target = String(removeBlockIndex++); }
87 | if(build.attbs) {
88 | sectionKey = [build.type, build.target, build.attbs].join(sectionsJoinChar);
89 | } else if (build.target) {
90 | sectionKey = [build.type, build.target].join(sectionsJoinChar);
91 | } else {
92 | sectionKey = build.type;
93 | }
94 |
95 | if (sections[sectionKey]) {
96 | sectionKey += sectionIndex++;
97 | }
98 |
99 | sections[sectionKey] = last = [];
100 | }
101 |
102 | // switch back block flag when endbuild
103 | if (block && endbuild) {
104 | last.push(l);
105 | block = false;
106 | }
107 |
108 | if (block && last) {
109 | last.push(l);
110 | }
111 | });
112 |
113 | // sections is an array of lines starting with the build block comment opener,
114 | // including all the references and including the build block comment closer.
115 | return sections;
116 | }
117 |
118 |
119 | // Helpers
120 | // -------
121 | var helpers = {
122 | // useref and useref:* are used with the blocks parsed from directives
123 | useref: function (content, block, target, type, attbs, alternateSearchPaths, handler) {
124 | var linefeed = /\r\n/g.test(content) ? '\r\n' : '\n',
125 | lines = block.split(linefeed),
126 | ref = '',
127 | indent = (lines[0].match(/^\s*/) || [])[0],
128 | ccmatches = block.match(regcc),
129 | blockContent = lines.slice(1, -1).join('');
130 |
131 | target = target || 'replace';
132 |
133 | if (type === 'css') {
134 |
135 | // Check to see if there are any css references at all.
136 | if( blockContent.search(regcss) !== -1 )
137 | {
138 | if(attbs) {
139 | ref = '';
140 | } else {
141 | ref = '';
142 | }
143 | }
144 |
145 | } else if (type === 'js') {
146 |
147 | // Check to see if there are any js references at all.
148 | if( blockContent.search(regscript) !== -1 )
149 | {
150 | if(attbs) {
151 | ref = '';
152 | } else {
153 | ref = '';
154 | }
155 | }
156 |
157 | } else if (type === 'remove') {
158 | ref = '';
159 | } else if (handler) {
160 | ref = handler(blockContent, target, attbs, alternateSearchPaths);
161 | }
162 | else {
163 | ref = null;
164 | }
165 |
166 | if(ref != null) {
167 | ref = indent + ref;
168 |
169 | // Reserve IE conditional comment if exist
170 | if (ccmatches) {
171 | ref = indent + ccmatches[1] + linefeed + ref + linefeed + indent + ccmatches[2];
172 | }
173 |
174 | return content.replace(block, ref);
175 | }
176 | else { return content; }
177 | }
178 | };
179 |
180 | function updateReferences(blocks, content, options) {
181 |
182 | // Determine the linefeed from the content
183 | var linefeed = /\r\n/g.test(content) ? '\r\n' : '\n';
184 |
185 | // handle blocks
186 | Object.keys(blocks).forEach(function (key) {
187 | var block = blocks[key].join(linefeed),
188 | parsed = parseBuildBlock(block),
189 | handler = options && options[parsed.type];
190 |
191 | content = helpers.useref(content, block, parsed.target, parsed.type, parsed.attbs, parsed.alternateSearchPaths, handler);
192 | });
193 |
194 | return content;
195 | }
196 |
197 | function removeComments(lines) {
198 | return lines.join('\n').replace(regComment, '').split('\n');
199 | }
200 |
201 | function compactContent(blocks) {
202 |
203 | var result = {};
204 |
205 | Object.keys(blocks).forEach(function (dest) {
206 | // Lines are the included scripts w/o the use blocks
207 | var lines = blocks[dest].slice(1, -1),
208 | parts = dest.split(sectionsJoinChar),
209 | type = parts[0],
210 | // output is the useref block file
211 | output = parts[1],
212 | build = parseBuildBlock(blocks[dest][0]);
213 |
214 | // remove html comment blocks
215 | lines = removeComments(lines);
216 |
217 | // parse out the list of assets to handle, and update the grunt config accordingly
218 | var assets = lines.map(function (tag) {
219 |
220 | // The asset is the string of the referenced source file
221 | var asset = (tag.match(/(href|src)=["']([^'"]+)["']/) || [])[2];
222 |
223 | // Allow white space and comment in build blocks by checking if this line has an asset or not
224 | if (asset) {
225 | return asset;
226 | }
227 |
228 | }).reduce(function (a, b) {
229 | return b ? a.concat(b) : a;
230 | }, []);
231 |
232 |
233 | result[type] = result[type] || {};
234 | result[type][output] = { 'assets': assets };
235 | if (build.alternateSearchPaths) {
236 | // Alternate search path
237 | result[type][output].searchPaths = build.alternateSearchPaths;
238 | }
239 | });
240 |
241 | return result;
242 | }
243 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | /* jshint node: true */
2 | /* global describe, it */
3 | 'use strict';
4 | var expect = require('chai').expect;
5 | var fs = require('fs');
6 | var path = require('path');
7 | var useRef = require('../src/index');
8 |
9 | function djoin(p) {
10 | return path.normalize(path.join(__dirname, p));
11 | }
12 | function fread(f) {
13 | return fs.readFileSync(f, { encoding: 'utf-8'});
14 | }
15 |
16 | describe('html-ref-replace', function() {
17 |
18 | it('should replace reference in css block and return replaced files', function() {
19 | var result = useRef(fread(djoin('testfiles/01.html')));
20 | expect(result[0]).to.equal(fread(djoin('testfiles/01-expected.html')));
21 | expect(result[1]).to.eql({ css: { '/css/combined.css': { 'assets': [ '/css/one.css', '/css/two.css' ] }}});
22 | });
23 |
24 | it('should replace reference in js block and return replaced files', function() {
25 | var result = useRef(fread(djoin('testfiles/02.html')));
26 | expect(result[0]).to.equal(fread(djoin('testfiles/02-expected.html')));
27 | expect(result[1]).to.eql({ js: { 'scripts/combined.concat.min.js': { 'assets': [ 'scripts/this.js', 'scripts/that.js' ] }}});
28 | });
29 |
30 | it('should remove `remove` block', function() {
31 | var result = useRef(fread(djoin('testfiles/09.html')));
32 | expect(result[0]).to.equal(fread(djoin('testfiles/09-expected.html')));
33 | expect(result[1]).to.eql({ remove: { '0': { 'assets': [ 'scripts/this.js', 'scripts/that.js' ] }}});
34 | });
35 |
36 | it('should remove multiple `remove` blocks', function() {
37 | var result = useRef(fread(djoin('testfiles/10.html')));
38 | expect(result[0]).to.equal(fread(djoin('testfiles/10-expected.html')));
39 | expect(result[1]).to.eql({ remove: { '0': { 'assets': [ 'scripts/this.js', 'scripts/that.js' ] }, '1': { 'assets': [ '/css/one.css', '/css/two.css' ] } }});
40 | });
41 |
42 | it('should handle comments and whitespace in blocks', function() {
43 | var result = useRef(fread(djoin('testfiles/03.html')));
44 | expect(result[0]).to.equal(fread(djoin('testfiles/03-expected.html')));
45 | expect(result[1]).to.eql({ js: { 'scripts/combined.concat.min.js': { 'assets': [ 'scripts/this.js', 'scripts/that.js' ] }}});
46 | });
47 |
48 | it('should handle comments and whitespace in blocks (without trailing space)', function() {
49 | var result = useRef(fread(djoin('testfiles/03b.html')));
50 | expect(result[0]).to.equal(fread(djoin('testfiles/03-expected.html')));
51 | expect(result[1]).to.eql({ js: { 'scripts/combined.concat.min.js': { 'assets': [ 'scripts/this.js', 'scripts/that.js' ] }}});
52 | });
53 |
54 | it('should ignore script in comments (multi line)', function() {
55 | var result = useRef(fread(djoin('testfiles/03c.html')));
56 | expect(result[0]).to.equal(fread(djoin('testfiles/03-expected.html')));
57 | expect(result[1]).to.eql({ js: { 'scripts/combined.concat.min.js': { 'assets': [ 'scripts/this.js' ] }}});
58 | });
59 |
60 | it('should ignore script in comments (single line with "