html-minifier 3.5.17 → 3.5.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -16
- package/cli.js +3 -3
- package/package.json +7 -7
- package/src/htmlminifier.js +77 -63
- package/src/htmlparser.js +2 -2
package/README.md
CHANGED
|
@@ -3,14 +3,12 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/html-minifier)
|
|
4
4
|
[](https://travis-ci.org/kangax/html-minifier)
|
|
5
5
|
[](https://david-dm.org/kangax/html-minifier)
|
|
6
|
-
[](https://david-dm.org/kangax/html-minifier?type=dev)
|
|
7
|
-
[](https://gitter.im/kangax/html-minifier)
|
|
8
6
|
|
|
9
|
-
[HTMLMinifier](
|
|
7
|
+
[HTMLMinifier](https://kangax.github.io/html-minifier/) is a highly **configurable**, **well-tested**, JavaScript-based HTML minifier.
|
|
10
8
|
|
|
11
9
|
See [corresponding blog post](http://perfectionkills.com/experimenting-with-html-minifier/) for all the gory details of [how it works](http://perfectionkills.com/experimenting-with-html-minifier/#how_it_works), [description of each option](http://perfectionkills.com/experimenting-with-html-minifier/#options), [testing results](http://perfectionkills.com/experimenting-with-html-minifier/#field_testing) and [conclusions](http://perfectionkills.com/experimenting-with-html-minifier/#cost_and_benefits).
|
|
12
10
|
|
|
13
|
-
[Test suite is available online](
|
|
11
|
+
[Test suite is available online](https://kangax.github.io/html-minifier/tests/).
|
|
14
12
|
|
|
15
13
|
Also see corresponding [Ruby wrapper](https://github.com/stereobooster/html_minifier), and for Node.js, [Grunt plugin](https://github.com/gruntjs/grunt-contrib-htmlmin), [Gulp module](https://github.com/jonschlinkert/gulp-htmlmin), [Koa middleware wrapper](https://github.com/koajs/html-minifier) and [Express middleware wrapper](https://github.com/melonmanchan/express-minify-html).
|
|
16
14
|
|
|
@@ -22,19 +20,19 @@ How does HTMLMinifier compare to other solutions — [HTML Minifier from Will Pe
|
|
|
22
20
|
|
|
23
21
|
| Site | Original size *(KB)* | HTMLMinifier | minimize | Will Peavy | htmlcompressor.com |
|
|
24
22
|
| ---------------------------------------------------------------------------- |:--------------------:| ------------:| --------:| ----------:| ------------------:|
|
|
25
|
-
| [Google](https://www.google.com/) |
|
|
26
|
-
| [
|
|
27
|
-
| [
|
|
28
|
-
| [
|
|
29
|
-
| [Stack Overflow](https://stackoverflow.com/) | 253 | **197** | 207 | 215 | 204 |
|
|
23
|
+
| [Google](https://www.google.com/) | 48 | **44** | 48 | 49 | 48 |
|
|
24
|
+
| [HTMLMinifier](https://github.com/kangax/html-minifier) | 154 | **117** | 128 | 133 | 128 |
|
|
25
|
+
| [Twitter](https://twitter.com/) | 203 | **162** | 195 | 219 | 195 |
|
|
26
|
+
| [Stack Overflow](https://stackoverflow.com/) | 254 | **196** | 208 | 216 | 205 |
|
|
30
27
|
| [Bootstrap CSS](https://getbootstrap.com/docs/3.3/css/) | 271 | **260** | 269 | 229 | 269 |
|
|
31
|
-
| [BBC](https://www.bbc.co.uk/) |
|
|
32
|
-
| [Amazon](https://www.amazon.co.uk/) |
|
|
33
|
-
| [Wikipedia](https://en.wikipedia.org/wiki/President_of_the_United_States) |
|
|
34
|
-
| [
|
|
28
|
+
| [BBC](https://www.bbc.co.uk/) | 288 | **230** | 280 | 281 | 272 |
|
|
29
|
+
| [Amazon](https://www.amazon.co.uk/) | 508 | **439** | 495 | 501 | n/a |
|
|
30
|
+
| [Wikipedia](https://en.wikipedia.org/wiki/President_of_the_United_States) | 533 | **434** | 517 | 536 | 517 |
|
|
31
|
+
| [New York Times](https://mathiasbynens.be/_tmp/nyt.html) | 699 | **619** | 693 | 683 | n/a |
|
|
32
|
+
| [NBC](https://www.nbc.com/) | 700 | **657** | 698 | 699 | n/a |
|
|
35
33
|
| [Eloquent Javascript](https://eloquentjavascript.net/1st_edition/print.html) | 870 | **815** | 840 | 864 | n/a |
|
|
36
|
-
| [ES6 table](https://kangax.github.io/compat-table/es6/) |
|
|
37
|
-
| [
|
|
34
|
+
| [ES6 table](https://kangax.github.io/compat-table/es6/) | 5308 | **4529** | 5025 | n/a | n/a |
|
|
35
|
+
| [ES draft](https://tc39.github.io/ecma262/) | 6082 | **5456** | 5624 | n/a | n/a |
|
|
38
36
|
|
|
39
37
|
## Options Quick Reference
|
|
40
38
|
|
|
@@ -138,7 +136,9 @@ npm link .
|
|
|
138
136
|
|
|
139
137
|
## Usage
|
|
140
138
|
|
|
141
|
-
For command line usage please see `html-minifier --help`
|
|
139
|
+
Note that almost all options are disabled by default. For command line usage please see `html-minifier --help` for a list of available options. Experiment and find what works best for you and your project.
|
|
140
|
+
|
|
141
|
+
* **Sample command line:** ``html-minifier --collapse-whitespace --remove-comments --remove-optional-tags --remove-redundant-attributes --remove-script-type-attributes --remove-tag-whitespace --use-short-doctype --minify-css true --minify-js true``
|
|
142
142
|
|
|
143
143
|
### Node.js
|
|
144
144
|
|
package/cli.js
CHANGED
|
@@ -140,7 +140,7 @@ var mainOptionKeys = Object.keys(mainOptions);
|
|
|
140
140
|
mainOptionKeys.forEach(function(key) {
|
|
141
141
|
var option = mainOptions[key];
|
|
142
142
|
if (Array.isArray(option)) {
|
|
143
|
-
key = '--' + paramCase(key);
|
|
143
|
+
key = key === 'minifyURLs' ? '--minify-urls' : '--' + paramCase(key);
|
|
144
144
|
key += option[1] === parseJSON ? ' [value]' : ' <value>';
|
|
145
145
|
program.option(key, option[0], option[1]);
|
|
146
146
|
}
|
|
@@ -197,7 +197,7 @@ program.arguments('[files...]').action(function(files) {
|
|
|
197
197
|
function createOptions() {
|
|
198
198
|
var options = {};
|
|
199
199
|
mainOptionKeys.forEach(function(key) {
|
|
200
|
-
var param = program[camelCase(key)];
|
|
200
|
+
var param = program[key === 'minifyURLs' ? 'minifyUrls' : camelCase(key)];
|
|
201
201
|
if (typeof param !== 'undefined') {
|
|
202
202
|
options[key] = param;
|
|
203
203
|
}
|
|
@@ -297,7 +297,7 @@ if (inputDir || outputDir) {
|
|
|
297
297
|
processDirectory(inputDir, outputDir, fileExt);
|
|
298
298
|
}
|
|
299
299
|
// Minifying one or more files specified on the CMD line
|
|
300
|
-
else if (
|
|
300
|
+
else if (content) {
|
|
301
301
|
writeMinify();
|
|
302
302
|
}
|
|
303
303
|
// Minifying input coming from STDIN
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "html-minifier",
|
|
3
3
|
"description": "Highly configurable, well-tested, JavaScript-based HTML minifier.",
|
|
4
|
-
"version": "3.5.
|
|
4
|
+
"version": "3.5.21",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
7
7
|
"compress",
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
"uglifier",
|
|
24
24
|
"uglify"
|
|
25
25
|
],
|
|
26
|
-
"homepage": "
|
|
26
|
+
"homepage": "https://kangax.github.io/html-minifier/",
|
|
27
27
|
"author": "Juriy \"kangax\" Zaytsev",
|
|
28
28
|
"maintainers": [
|
|
29
29
|
"Alex Lam <alexlamsl@gmail.com>",
|
|
30
|
-
"Juriy Zaytsev <kangax@gmail.com> (http://perfectionkills.com)"
|
|
30
|
+
"Juriy Zaytsev <kangax@gmail.com> (http://perfectionkills.com/)"
|
|
31
31
|
],
|
|
32
32
|
"contributors": [
|
|
33
33
|
"Gilmore Davidson (https://github.com/gilmoreorless)",
|
|
@@ -55,9 +55,9 @@
|
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"camel-case": "3.0.x",
|
|
58
|
-
"clean-css": "4.
|
|
59
|
-
"commander": "2.
|
|
60
|
-
"he": "1.
|
|
58
|
+
"clean-css": "4.2.x",
|
|
59
|
+
"commander": "2.17.x",
|
|
60
|
+
"he": "1.2.x",
|
|
61
61
|
"param-case": "2.1.x",
|
|
62
62
|
"relateurl": "0.2.x",
|
|
63
63
|
"uglify-js": "3.4.x"
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"grunt": "1.0.x",
|
|
67
67
|
"grunt-browserify": "5.3.x",
|
|
68
|
-
"grunt-contrib-uglify": "3.
|
|
68
|
+
"grunt-contrib-uglify": "3.4.x",
|
|
69
69
|
"gruntify-eslint": "4.0.x",
|
|
70
70
|
"phantomjs-prebuilt": "2.1.x",
|
|
71
71
|
"qunit": "2.x"
|
package/src/htmlminifier.js
CHANGED
|
@@ -109,7 +109,7 @@ function isEventAttribute(attrName, options) {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
function canRemoveAttributeQuotes(value) {
|
|
112
|
-
//
|
|
112
|
+
// https://mathiasbynens.be/notes/unquoted-attribute-values
|
|
113
113
|
return /^[^ \t\n\f\r"'`=<>]+$/.test(value);
|
|
114
114
|
}
|
|
115
115
|
|
|
@@ -335,23 +335,33 @@ function isMetaViewport(tag, attrs) {
|
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
function wrapInlineCSS(text) {
|
|
341
|
-
return '*{' + text + '}';
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
function unwrapInlineCSS(text) {
|
|
345
|
-
var matches = text.match(/^\*\{([\s\S]*)\}$/);
|
|
346
|
-
return matches ? matches[1] : text;
|
|
338
|
+
function ignoreCSS(id) {
|
|
339
|
+
return '/* clean-css ignore:start */' + id + '/* clean-css ignore:end */';
|
|
347
340
|
}
|
|
348
341
|
|
|
349
|
-
|
|
350
|
-
|
|
342
|
+
// Wrap CSS declarations for CleanCSS > 3.x
|
|
343
|
+
// See https://github.com/jakubpawlowicz/clean-css/issues/418
|
|
344
|
+
function wrapCSS(text, type) {
|
|
345
|
+
switch (type) {
|
|
346
|
+
case 'inline':
|
|
347
|
+
return '*{' + text + '}';
|
|
348
|
+
case 'media':
|
|
349
|
+
return '@media ' + text + '{a{top:0}}';
|
|
350
|
+
default:
|
|
351
|
+
return text;
|
|
352
|
+
}
|
|
351
353
|
}
|
|
352
354
|
|
|
353
|
-
function
|
|
354
|
-
var matches
|
|
355
|
+
function unwrapCSS(text, type) {
|
|
356
|
+
var matches;
|
|
357
|
+
switch (type) {
|
|
358
|
+
case 'inline':
|
|
359
|
+
matches = text.match(/^\*\{([\s\S]*)\}$/);
|
|
360
|
+
break;
|
|
361
|
+
case 'media':
|
|
362
|
+
matches = text.match(/^@media ([\s\S]*?)\s*{[\s\S]*}$/);
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
355
365
|
return matches ? matches[1] : text;
|
|
356
366
|
}
|
|
357
367
|
|
|
@@ -374,7 +384,7 @@ function processScript(text, options, currentAttrs) {
|
|
|
374
384
|
// Tag omission rules from https://html.spec.whatwg.org/multipage/syntax.html#optional-tags
|
|
375
385
|
// with the following deviations:
|
|
376
386
|
// - retain <body> if followed by <noscript>
|
|
377
|
-
// - </rb>, </rt>, </rtc>, </rp> & </tfoot> follow
|
|
387
|
+
// - </rb>, </rt>, </rtc>, </rp> & </tfoot> follow https://www.w3.org/TR/html5/syntax.html#optional-tags
|
|
378
388
|
// - retain all tags which are adjacent to non-standard HTML tags
|
|
379
389
|
var optionalStartTags = createMapFromString('html,head,body,colgroup,tbody');
|
|
380
390
|
var optionalEndTags = createMapFromString('html,head,body,li,dt,dd,p,rb,rt,rtc,rp,optgroup,option,colgroup,caption,thead,tbody,tfoot,tr,td,th');
|
|
@@ -654,26 +664,12 @@ function processOptions(values) {
|
|
|
654
664
|
text = text.replace(/(url\s*\(\s*)("|'|)(.*?)\2(\s*\))/ig, function(match, prefix, quote, url, suffix) {
|
|
655
665
|
return prefix + quote + options.minifyURLs(url) + quote + suffix;
|
|
656
666
|
});
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
}
|
|
661
|
-
else if (type === 'media') {
|
|
662
|
-
text = wrapMediaQuery(text);
|
|
663
|
-
}
|
|
664
|
-
text = new CleanCSS(value).minify(text).styles;
|
|
665
|
-
if (type === 'inline') {
|
|
666
|
-
text = unwrapInlineCSS(text);
|
|
667
|
-
}
|
|
668
|
-
else if (type === 'media') {
|
|
669
|
-
text = unwrapMediaQuery(text);
|
|
670
|
-
}
|
|
671
|
-
return text;
|
|
672
|
-
}
|
|
673
|
-
catch (err) {
|
|
674
|
-
options.log(err);
|
|
667
|
+
var cleanCssOutput = new CleanCSS(value).minify(wrapCSS(text, type));
|
|
668
|
+
if (cleanCssOutput.errors.length > 0) {
|
|
669
|
+
cleanCssOutput.errors.forEach(options.log);
|
|
675
670
|
return text;
|
|
676
671
|
}
|
|
672
|
+
return unwrapCSS(cleanCssOutput.styles, type);
|
|
677
673
|
};
|
|
678
674
|
}
|
|
679
675
|
else if (key === 'minifyJS' && typeof value !== 'function') {
|
|
@@ -859,15 +855,6 @@ function minify(value, options, partialMarkup) {
|
|
|
859
855
|
return token;
|
|
860
856
|
});
|
|
861
857
|
|
|
862
|
-
function escapeFragments(fn) {
|
|
863
|
-
return function(text, type) {
|
|
864
|
-
return fn(text.replace(uidPattern, function(match, prefix, index) {
|
|
865
|
-
var chunks = ignoredCustomMarkupChunks[+index];
|
|
866
|
-
return chunks[1] + uidAttr + index + chunks[2];
|
|
867
|
-
}), type);
|
|
868
|
-
};
|
|
869
|
-
}
|
|
870
|
-
|
|
871
858
|
var customFragments = options.ignoreCustomFragments.map(function(re) {
|
|
872
859
|
return re.source;
|
|
873
860
|
});
|
|
@@ -879,10 +866,38 @@ function minify(value, options, partialMarkup) {
|
|
|
879
866
|
uidAttr = uniqueId(value);
|
|
880
867
|
uidPattern = new RegExp('(\\s*)' + uidAttr + '([0-9]+)(\\s*)', 'g');
|
|
881
868
|
if (options.minifyCSS) {
|
|
882
|
-
options.minifyCSS =
|
|
869
|
+
options.minifyCSS = (function(fn) {
|
|
870
|
+
return function(text, type) {
|
|
871
|
+
text = text.replace(uidPattern, function(match, prefix, index) {
|
|
872
|
+
var chunks = ignoredCustomMarkupChunks[+index];
|
|
873
|
+
return chunks[1] + uidAttr + index + chunks[2];
|
|
874
|
+
});
|
|
875
|
+
var ids = [];
|
|
876
|
+
new CleanCSS().minify(wrapCSS(text, type)).warnings.forEach(function(warning) {
|
|
877
|
+
var match = uidPattern.exec(warning);
|
|
878
|
+
if (match) {
|
|
879
|
+
var id = uidAttr + match[2];
|
|
880
|
+
text = text.replace(id, ignoreCSS(id));
|
|
881
|
+
ids.push(id);
|
|
882
|
+
}
|
|
883
|
+
});
|
|
884
|
+
text = fn(text, type);
|
|
885
|
+
ids.forEach(function(id) {
|
|
886
|
+
text = text.replace(ignoreCSS(id), id);
|
|
887
|
+
});
|
|
888
|
+
return text;
|
|
889
|
+
};
|
|
890
|
+
})(options.minifyCSS);
|
|
883
891
|
}
|
|
884
892
|
if (options.minifyJS) {
|
|
885
|
-
options.minifyJS =
|
|
893
|
+
options.minifyJS = (function(fn) {
|
|
894
|
+
return function(text, type) {
|
|
895
|
+
return fn(text.replace(uidPattern, function(match, prefix, index) {
|
|
896
|
+
var chunks = ignoredCustomMarkupChunks[+index];
|
|
897
|
+
return chunks[1] + uidAttr + index + chunks[2];
|
|
898
|
+
}), type);
|
|
899
|
+
};
|
|
900
|
+
})(options.minifyJS);
|
|
886
901
|
}
|
|
887
902
|
}
|
|
888
903
|
var token = uidAttr + ignoredCustomMarkupChunks.length;
|
|
@@ -1180,9 +1195,12 @@ function minify(value, options, partialMarkup) {
|
|
|
1180
1195
|
}
|
|
1181
1196
|
charsPrevTag = /^\s*$/.test(text) ? prevTag : 'comment';
|
|
1182
1197
|
if (options.decodeEntities && text && !specialContentTags(currentTag)) {
|
|
1183
|
-
//
|
|
1198
|
+
// Escape any `&` symbols that start either:
|
|
1199
|
+
// 1) a legacy named character reference (i.e. one that doesn't end with `;`)
|
|
1200
|
+
// 2) or any other character reference (i.e. one that does end with `;`)
|
|
1201
|
+
// Note that `&` can be escaped as `&`, without the semi-colon.
|
|
1184
1202
|
// https://mathiasbynens.be/notes/ambiguous-ampersands
|
|
1185
|
-
text = text.replace(/&(
|
|
1203
|
+
text = text.replace(/&((?:Iacute|aacute|uacute|plusmn|Otilde|otilde|agrave|Agrave|Yacute|yacute|Oslash|oslash|atilde|Atilde|brvbar|ccedil|Ccedil|Ograve|curren|divide|eacute|Eacute|ograve|Oacute|egrave|Egrave|Ugrave|frac12|frac14|frac34|ugrave|oacute|iacute|Ntilde|ntilde|Uacute|middot|igrave|Igrave|iquest|Aacute|cedil|laquo|micro|iexcl|Icirc|icirc|acirc|Ucirc|Ecirc|ocirc|Ocirc|ecirc|ucirc|Aring|aring|AElig|aelig|acute|pound|raquo|Acirc|times|THORN|szlig|thorn|COPY|auml|ordf|ordm|Uuml|macr|uuml|Auml|ouml|Ouml|para|nbsp|euml|quot|QUOT|Euml|yuml|cent|sect|copy|sup1|sup2|sup3|iuml|Iuml|ETH|shy|reg|not|yen|amp|AMP|REG|uml|eth|deg|gt|GT|LT|lt)(?!;)|(?:#?[0-9a-zA-Z]+;))/g, '&$1').replace(/</g, '<');
|
|
1186
1204
|
}
|
|
1187
1205
|
if (uidPattern && options.collapseWhitespace && stackNoTrimWhitespace.length) {
|
|
1188
1206
|
text = text.replace(uidPattern, function(match, prefix, index) {
|
|
@@ -1220,7 +1238,9 @@ function minify(value, options, partialMarkup) {
|
|
|
1220
1238
|
buffer.push(text);
|
|
1221
1239
|
},
|
|
1222
1240
|
doctype: function(doctype) {
|
|
1223
|
-
buffer.push(options.useShortDoctype ? '<!
|
|
1241
|
+
buffer.push(options.useShortDoctype ? '<!doctype' +
|
|
1242
|
+
(options.removeTagWhitespace ? '' : ' ') + 'html>' :
|
|
1243
|
+
collapseWhitespaceAll(doctype));
|
|
1224
1244
|
},
|
|
1225
1245
|
customAttrAssign: options.customAttrAssign,
|
|
1226
1246
|
customAttrSurround: options.customAttrSurround
|
|
@@ -1241,10 +1261,8 @@ function minify(value, options, partialMarkup) {
|
|
|
1241
1261
|
squashTrailingWhitespace('br');
|
|
1242
1262
|
}
|
|
1243
1263
|
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
if (uidPattern) {
|
|
1247
|
-
str = str.replace(uidPattern, function(match, prefix, index, suffix) {
|
|
1264
|
+
return joinResultSegments(buffer, options, uidPattern ? function(str) {
|
|
1265
|
+
return str.replace(uidPattern, function(match, prefix, index, suffix) {
|
|
1248
1266
|
var chunk = ignoredCustomMarkupChunks[+index][0];
|
|
1249
1267
|
if (options.collapseWhitespace) {
|
|
1250
1268
|
if (prefix !== '\t') {
|
|
@@ -1260,17 +1278,14 @@ function minify(value, options, partialMarkup) {
|
|
|
1260
1278
|
}
|
|
1261
1279
|
return chunk;
|
|
1262
1280
|
});
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
|
-
str = str.replace(new RegExp('<!--' + uidIgnore + '([0-9]+)-->', 'g'), function(match, index) {
|
|
1281
|
+
} : identity, uidIgnore ? function(str) {
|
|
1282
|
+
return str.replace(new RegExp('<!--' + uidIgnore + '([0-9]+)-->', 'g'), function(match, index) {
|
|
1266
1283
|
return ignoredMarkupChunks[+index];
|
|
1267
1284
|
});
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
return str;
|
|
1285
|
+
} : identity);
|
|
1271
1286
|
}
|
|
1272
1287
|
|
|
1273
|
-
function joinResultSegments(results, options) {
|
|
1288
|
+
function joinResultSegments(results, options, restoreCustom, restoreIgnore) {
|
|
1274
1289
|
var str;
|
|
1275
1290
|
var maxLineLength = options.maxLineLength;
|
|
1276
1291
|
if (maxLineLength) {
|
|
@@ -1279,13 +1294,13 @@ function joinResultSegments(results, options) {
|
|
|
1279
1294
|
var len = line.length;
|
|
1280
1295
|
var end = results[0].indexOf('\n');
|
|
1281
1296
|
if (end < 0) {
|
|
1282
|
-
line += results.shift();
|
|
1297
|
+
line += restoreIgnore(restoreCustom(results.shift()));
|
|
1283
1298
|
}
|
|
1284
1299
|
else {
|
|
1285
|
-
line += results[0].slice(0, end);
|
|
1300
|
+
line += restoreIgnore(restoreCustom(results[0].slice(0, end)));
|
|
1286
1301
|
results[0] = results[0].slice(end + 1);
|
|
1287
1302
|
}
|
|
1288
|
-
if (len > 0 && line.length
|
|
1303
|
+
if (len > 0 && line.length > maxLineLength) {
|
|
1289
1304
|
lines.push(line.slice(0, len));
|
|
1290
1305
|
line = line.slice(len);
|
|
1291
1306
|
}
|
|
@@ -1297,11 +1312,10 @@ function joinResultSegments(results, options) {
|
|
|
1297
1312
|
if (line) {
|
|
1298
1313
|
lines.push(line);
|
|
1299
1314
|
}
|
|
1300
|
-
|
|
1301
1315
|
str = lines.join('\n');
|
|
1302
1316
|
}
|
|
1303
1317
|
else {
|
|
1304
|
-
str = results.join('');
|
|
1318
|
+
str = restoreIgnore(restoreCustom(results.join('')));
|
|
1305
1319
|
}
|
|
1306
1320
|
return options.collapseWhitespace ? collapseWhitespace(str, options, true, true) : str;
|
|
1307
1321
|
}
|
package/src/htmlparser.js
CHANGED
|
@@ -60,7 +60,7 @@ var singleAttrIdentifier = /([^\s"'<>/=]+)/,
|
|
|
60
60
|
startTagOpen = new RegExp('^<' + qnameCapture),
|
|
61
61
|
startTagClose = /^\s*(\/?)>/,
|
|
62
62
|
endTag = new RegExp('^<\\/' + qnameCapture + '[^>]*>'),
|
|
63
|
-
doctype = /^<!DOCTYPE
|
|
63
|
+
doctype = /^<!DOCTYPE\s?[^>]+>/i;
|
|
64
64
|
|
|
65
65
|
var IS_REGEX_CAPTURING_BROKEN = false;
|
|
66
66
|
'x'.replace(/x(.)?/g, function(m, g) {
|
|
@@ -140,7 +140,7 @@ function HTMLParser(html, handler) {
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
//
|
|
143
|
+
// https://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment
|
|
144
144
|
if (/^<!\[/.test(html)) {
|
|
145
145
|
var conditionalEnd = html.indexOf(']>');
|
|
146
146
|
|