html-minifier 1.4.0 → 1.5.0
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 +42 -34
- package/cli.js +218 -282
- package/package.json +4 -8
- package/sample-cli-config-file.conf +27 -18
- package/src/htmllint.js +67 -55
- package/src/htmlminifier.js +223 -114
- package/src/htmlparser.js +132 -130
- package/src/tokenchain.js +58 -0
- package/CHANGELOG.md +0 -120
- package/dist/htmlminifier.js +0 -32753
- package/dist/htmlminifier.min.js +0 -18
package/src/htmllint.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* HTMLLint (to be used in conjunction with HTMLMinifier)
|
|
3
3
|
*
|
|
4
|
-
* Copyright (c) 2010-
|
|
4
|
+
* Copyright (c) 2010-2016 Juriy "kangax" Zaytsev
|
|
5
5
|
* Licensed under the MIT license.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
@@ -9,67 +9,65 @@
|
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
11
11
|
function isPresentationalElement(tag) {
|
|
12
|
-
return
|
|
12
|
+
return /^(?:big|small|hr|blink|marquee)$/.test(tag);
|
|
13
13
|
}
|
|
14
14
|
function isDeprecatedElement(tag) {
|
|
15
|
-
return
|
|
15
|
+
return /^(?:applet|basefont|center|dir|font|isindex|strike)$/.test(tag);
|
|
16
16
|
}
|
|
17
17
|
function isEventAttribute(attrName) {
|
|
18
|
-
return
|
|
18
|
+
return /^on[a-z]+/.test(attrName);
|
|
19
19
|
}
|
|
20
20
|
function isStyleAttribute(attrName) {
|
|
21
|
-
return
|
|
21
|
+
return attrName.toLowerCase() === 'style';
|
|
22
22
|
}
|
|
23
23
|
function isDeprecatedAttribute(tag, attrName) {
|
|
24
24
|
return (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
25
|
+
attrName === 'align' &&
|
|
26
|
+
/^(?:caption|applet|iframe|img|imput|object|legend|table|hr|div|h[1-6]|p)$/.test(tag) ||
|
|
27
|
+
attrName === 'alink' && tag === 'body' ||
|
|
28
|
+
attrName === 'alt' && tag === 'applet' ||
|
|
29
|
+
attrName === 'archive' && tag === 'applet' ||
|
|
30
|
+
attrName === 'background' && tag === 'body' ||
|
|
31
|
+
attrName === 'bgcolor' && /^(?:table|t[rdh]|body)$/.test(tag) ||
|
|
32
|
+
attrName === 'border' && /^(?:img|object)$/.test(tag) ||
|
|
33
|
+
attrName === 'clear' && tag === 'br' ||
|
|
34
|
+
attrName === 'code' && tag === 'applet' ||
|
|
35
|
+
attrName === 'codebase' && tag === 'applet' ||
|
|
36
|
+
attrName === 'color' && /^(?:base(?:font)?)$/.test(tag) ||
|
|
37
|
+
attrName === 'compact' && /^(?:dir|[dou]l|menu)$/.test(tag) ||
|
|
38
|
+
attrName === 'face' && /^base(?:font)?$/.test(tag) ||
|
|
39
|
+
attrName === 'height' && /^(?:t[dh]|applet)$/.test(tag) ||
|
|
40
|
+
attrName === 'hspace' && /^(?:applet|img|object)$/.test(tag) ||
|
|
41
|
+
attrName === 'language' && tag === 'script' ||
|
|
42
|
+
attrName === 'link' && tag === 'body' ||
|
|
43
|
+
attrName === 'name' && tag === 'applet' ||
|
|
44
|
+
attrName === 'noshade' && tag === 'hr' ||
|
|
45
|
+
attrName === 'nowrap' && /^t[dh]$/.test(tag) ||
|
|
46
|
+
attrName === 'object' && tag === 'applet' ||
|
|
47
|
+
attrName === 'prompt' && tag === 'isindex' ||
|
|
48
|
+
attrName === 'size' && /^(?:hr|font|basefont)$/.test(tag) ||
|
|
49
|
+
attrName === 'start' && tag === 'ol' ||
|
|
50
|
+
attrName === 'text' && tag === 'body' ||
|
|
51
|
+
attrName === 'type' && /^(?:li|ol|ul)$/.test(tag) ||
|
|
52
|
+
attrName === 'value' && tag === 'li' ||
|
|
53
|
+
attrName === 'version' && tag === 'html' ||
|
|
54
|
+
attrName === 'vlink' && tag === 'body' ||
|
|
55
|
+
attrName === 'vspace' && /^(?:applet|img|object)$/.test(tag) ||
|
|
56
|
+
attrName === 'width' && /^(?:hr|td|th|applet|pre)$/.test(tag)
|
|
57
57
|
);
|
|
58
58
|
}
|
|
59
59
|
function isInaccessibleAttribute(attrName, attrValue) {
|
|
60
|
-
return (
|
|
61
|
-
attrName === 'href' &&
|
|
62
|
-
(/^\s*javascript\s*:\s*void\s*(\s+0|\(\s*0\s*\))\s*$/i).test(attrValue)
|
|
63
|
-
);
|
|
60
|
+
return attrName === 'href' && /^\s*javascript\s*:\s*void\s*(\s+0|\(\s*0\s*\))\s*$/i.test(attrValue);
|
|
64
61
|
}
|
|
65
62
|
|
|
66
63
|
function Lint() {
|
|
67
|
-
this.log = [
|
|
64
|
+
this.log = [];
|
|
68
65
|
this._lastElement = null;
|
|
69
66
|
this._isElementRepeated = false;
|
|
70
67
|
}
|
|
71
68
|
|
|
72
69
|
Lint.prototype.testElement = function(tag) {
|
|
70
|
+
this._attributes = Object.create(null);
|
|
73
71
|
if (isDeprecatedElement(tag)) {
|
|
74
72
|
this.log.push(
|
|
75
73
|
'Found <span class="deprecated-element">deprecated</span> <strong><code><' +
|
|
@@ -103,6 +101,15 @@ Lint.prototype._reportRepeatingElement = function() {
|
|
|
103
101
|
};
|
|
104
102
|
|
|
105
103
|
Lint.prototype.testAttribute = function(tag, attrName, attrValue) {
|
|
104
|
+
if (this._attributes[attrName]) {
|
|
105
|
+
this.log.push(
|
|
106
|
+
'Found <span class="repeating-attribute">repeating attribute</span> (<strong>' +
|
|
107
|
+
attrName + '</strong>) on <strong><code><' + tag + '></code></strong> element.'
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
this._attributes[attrName] = true;
|
|
112
|
+
}
|
|
106
113
|
if (isEventAttribute(attrName)) {
|
|
107
114
|
this.log.push(
|
|
108
115
|
'Found <span class="event-attribute">event attribute</span> (<strong>' +
|
|
@@ -141,24 +148,29 @@ Lint.prototype.test = function(tag, attrName, attrValue) {
|
|
|
141
148
|
this.testAttribute(tag, attrName, attrValue);
|
|
142
149
|
};
|
|
143
150
|
|
|
151
|
+
Lint.prototype.testDoctype = function(doctype) {
|
|
152
|
+
this._doctype = doctype;
|
|
153
|
+
};
|
|
154
|
+
|
|
144
155
|
Lint.prototype.populate = function(writeToElement) {
|
|
156
|
+
if (!this._doctype) {
|
|
157
|
+
this.log.push('No DOCTYPE found.');
|
|
158
|
+
}
|
|
159
|
+
|
|
145
160
|
if (this._isElementRepeated) {
|
|
146
161
|
this._reportRepeatingElement();
|
|
147
162
|
}
|
|
148
163
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
console.log(output);
|
|
161
|
-
}
|
|
164
|
+
var output;
|
|
165
|
+
if (writeToElement) {
|
|
166
|
+
output = this.log.map(function(line) {
|
|
167
|
+
return '<li>' + line + '</li>';
|
|
168
|
+
}).join('');
|
|
169
|
+
writeToElement.innerHTML = '<ol>' + output + '</ol>';
|
|
170
|
+
}
|
|
171
|
+
else if (this.log.length) {
|
|
172
|
+
output = this.log.join('\n - ').replace(/<[^>]+>/g, '');
|
|
173
|
+
console.log(' - ' + output.replace(/</g, '<').replace(/>/g, '>'));
|
|
162
174
|
}
|
|
163
175
|
};
|
|
164
176
|
|