html-minifier 1.3.1 → 1.4.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "html-minifier",
3
3
  "description": "HTML minifier with lint-like capabilities.",
4
- "version": "1.3.1",
4
+ "version": "1.4.0",
5
5
  "keywords": [
6
6
  "html",
7
7
  "minifier",
@@ -33,11 +33,7 @@
33
33
  "node": ">=0.10.0"
34
34
  },
35
35
  "scripts": {
36
- "assets": "grunt assets",
37
- "assets/clean-css": "browserify node_modules/clean-css/ --standalone CleanCSS | uglifyjs --compress --mangle -o assets/cleancss-browser.js",
38
- "assets/ncname": "browserify node_modules/ncname/ --standalone NCName | uglifyjs --compress --mangle -o assets/ncname-browser.js",
39
- "assets/relateurl": "browserify node_modules/relateurl/ --standalone RelateUrl | uglifyjs --compress --mangle -o assets/relateurl-browser.js",
40
- "assets/uglify-js": "browserify node_modules/uglify-js/ --standalone UglifyJS | uglifyjs --compress --mangle -o assets/uglify-browser.js",
36
+ "dist": "grunt dist",
41
37
  "test": "grunt test"
42
38
  },
43
39
  "dependencies": {
@@ -50,13 +46,12 @@
50
46
  "uglify-js": "2.6.x"
51
47
  },
52
48
  "devDependencies": {
53
- "browserify": "13.0.x",
54
- "brotli": "1.1.x",
49
+ "brotli": "1.2.x",
55
50
  "chalk": "1.1.x",
56
51
  "cli-table": "0.3.x",
57
52
  "grunt": "0.4.x",
53
+ "grunt-browserify": "5.0.x",
58
54
  "grunt-cli": "1.1.x",
59
- "grunt-contrib-concat": "1.0.x",
60
55
  "grunt-contrib-uglify": "1.0.x",
61
56
  "grunt-eslint": "18.0.x",
62
57
  "grunt-exec": "0.4.x",
@@ -1,7 +1,5 @@
1
1
  {
2
2
  "removeComments": true,
3
- "removeCommentsFromCDATA": true,
4
- "removeCDATASectionsFromCDATA": true,
5
3
  "collapseWhitespace": true,
6
4
  "conservativeCollapse": false,
7
5
  "collapseBooleanAttributes": true,
@@ -20,7 +18,11 @@
20
18
  "minifyJS": true,
21
19
  "minifyCSS": true,
22
20
  "includeAutoGeneratedTags": false,
23
- "ignoreCustomComments": [],
21
+ "ignoreCustomFragments": [
22
+ "<#[\\s\\S]*?#>"
23
+ ],
24
24
  "processConditionalComments": true,
25
- "processScripts": []
25
+ "processScripts": [
26
+ "text/html"
27
+ ]
26
28
  }
package/src/htmllint.js CHANGED
@@ -6,163 +6,160 @@
6
6
  *
7
7
  */
8
8
 
9
- (function(global) {
10
- 'use strict';
9
+ 'use strict';
11
10
 
12
- function isPresentationalElement(tag) {
13
- return (/^(?:big|small|hr|blink|marquee)$/).test(tag);
14
- }
15
- function isDeprecatedElement(tag) {
16
- return (/^(?:applet|basefont|center|dir|font|isindex|strike)$/).test(tag);
17
- }
18
- function isEventAttribute(attrName) {
19
- return (/^on[a-z]+/).test(attrName);
20
- }
21
- function isStyleAttribute(attrName) {
22
- return (attrName.toLowerCase() === 'style');
23
- }
24
- function isDeprecatedAttribute(tag, attrName) {
25
- return (
26
- (attrName === 'align' &&
27
- (/^(?:caption|applet|iframe|img|imput|object|legend|table|hr|div|h[1-6]|p)$/).test(tag)) ||
28
- (attrName === 'alink' && tag === 'body') ||
29
- (attrName === 'alt' && tag === 'applet') ||
30
- (attrName === 'archive' && tag === 'applet') ||
31
- (attrName === 'background' && tag === 'body') ||
32
- (attrName === 'bgcolor' && (/^(?:table|t[rdh]|body)$/).test(tag)) ||
33
- (attrName === 'border' && (/^(?:img|object)$/).test(tag)) ||
34
- (attrName === 'clear' && tag === 'br') ||
35
- (attrName === 'code' && tag === 'applet') ||
36
- (attrName === 'codebase' && tag === 'applet') ||
37
- (attrName === 'color' && (/^(?:base(?:font)?)$/).test(tag)) ||
38
- (attrName === 'compact' && (/^(?:dir|[dou]l|menu)$/).test(tag)) ||
39
- (attrName === 'face' && (/^base(?:font)?$/).test(tag)) ||
40
- (attrName === 'height' && (/^(?:t[dh]|applet)$/).test(tag)) ||
41
- (attrName === 'hspace' && (/^(?:applet|img|object)$/).test(tag)) ||
42
- (attrName === 'language' && tag === 'script') ||
43
- (attrName === 'link' && tag === 'body') ||
44
- (attrName === 'name' && tag === 'applet') ||
45
- (attrName === 'noshade' && tag === 'hr') ||
46
- (attrName === 'nowrap' && (/^t[dh]$/).test(tag)) ||
47
- (attrName === 'object' && tag === 'applet') ||
48
- (attrName === 'prompt' && tag === 'isindex') ||
49
- (attrName === 'size' && (/^(?:hr|font|basefont)$/).test(tag)) ||
50
- (attrName === 'start' && tag === 'ol') ||
51
- (attrName === 'text' && tag === 'body') ||
52
- (attrName === 'type' && (/^(?:li|ol|ul)$/).test(tag)) ||
53
- (attrName === 'value' && tag === 'li') ||
54
- (attrName === 'version' && tag === 'html') ||
55
- (attrName === 'vlink' && tag === 'body') ||
56
- (attrName === 'vspace' && (/^(?:applet|img|object)$/).test(tag)) ||
57
- (attrName === 'width' && (/^(?:hr|td|th|applet|pre)$/).test(tag))
11
+ function isPresentationalElement(tag) {
12
+ return (/^(?:big|small|hr|blink|marquee)$/).test(tag);
13
+ }
14
+ function isDeprecatedElement(tag) {
15
+ return (/^(?:applet|basefont|center|dir|font|isindex|strike)$/).test(tag);
16
+ }
17
+ function isEventAttribute(attrName) {
18
+ return (/^on[a-z]+/).test(attrName);
19
+ }
20
+ function isStyleAttribute(attrName) {
21
+ return (attrName.toLowerCase() === 'style');
22
+ }
23
+ function isDeprecatedAttribute(tag, attrName) {
24
+ return (
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
+ );
58
+ }
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
+ );
64
+ }
65
+
66
+ function Lint() {
67
+ this.log = [ ];
68
+ this._lastElement = null;
69
+ this._isElementRepeated = false;
70
+ }
71
+
72
+ Lint.prototype.testElement = function(tag) {
73
+ if (isDeprecatedElement(tag)) {
74
+ this.log.push(
75
+ 'Found <span class="deprecated-element">deprecated</span> <strong><code>&lt;' +
76
+ tag + '&gt;</code></strong> element'
58
77
  );
59
78
  }
60
- function isInaccessibleAttribute(attrName, attrValue) {
61
- return (
62
- attrName === 'href' &&
63
- (/^\s*javascript\s*:\s*void\s*(\s+0|\(\s*0\s*\))\s*$/i).test(attrValue)
79
+ else if (isPresentationalElement(tag)) {
80
+ this.log.push(
81
+ 'Found <span class="presentational-element">presentational</span> <strong><code>&lt;' +
82
+ tag + '&gt;</code></strong> element'
64
83
  );
65
84
  }
85
+ else {
86
+ this.checkRepeatingElement(tag);
87
+ }
88
+ };
66
89
 
67
- function Lint() {
68
- this.log = [ ];
69
- this._lastElement = null;
90
+ Lint.prototype.checkRepeatingElement = function(tag) {
91
+ if (tag === 'br' && this._lastElement === 'br') {
92
+ this._isElementRepeated = true;
93
+ }
94
+ else if (this._isElementRepeated) {
95
+ this._reportRepeatingElement();
70
96
  this._isElementRepeated = false;
71
97
  }
98
+ this._lastElement = tag;
99
+ };
72
100
 
73
- Lint.prototype.testElement = function(tag) {
74
- if (isDeprecatedElement(tag)) {
75
- this.log.push(
76
- 'Found <span class="deprecated-element">deprecated</span> <strong><code>&lt;' +
77
- tag + '&gt;</code></strong> element'
78
- );
79
- }
80
- else if (isPresentationalElement(tag)) {
81
- this.log.push(
82
- 'Found <span class="presentational-element">presentational</span> <strong><code>&lt;' +
83
- tag + '&gt;</code></strong> element'
84
- );
85
- }
86
- else {
87
- this.checkRepeatingElement(tag);
88
- }
89
- };
90
-
91
- Lint.prototype.checkRepeatingElement = function(tag) {
92
- if (tag === 'br' && this._lastElement === 'br') {
93
- this._isElementRepeated = true;
94
- }
95
- else if (this._isElementRepeated) {
96
- this._reportRepeatingElement();
97
- this._isElementRepeated = false;
98
- }
99
- this._lastElement = tag;
100
- };
101
+ Lint.prototype._reportRepeatingElement = function() {
102
+ this.log.push('Found <code>&lt;br></code> sequence. Try replacing it with styling.');
103
+ };
101
104
 
102
- Lint.prototype._reportRepeatingElement = function() {
103
- this.log.push('Found <code>&lt;br></code> sequence. Try replacing it with styling.');
104
- };
105
+ Lint.prototype.testAttribute = function(tag, attrName, attrValue) {
106
+ if (isEventAttribute(attrName)) {
107
+ this.log.push(
108
+ 'Found <span class="event-attribute">event attribute</span> (<strong>' +
109
+ attrName + '</strong>) on <strong><code>&lt;' + tag + '&gt;</code></strong> element.'
110
+ );
111
+ }
112
+ else if (isDeprecatedAttribute(tag, attrName)) {
113
+ this.log.push(
114
+ 'Found <span class="deprecated-attribute">deprecated</span> <strong>' +
115
+ attrName + '</strong> attribute on <strong><code>&lt;' + tag + '&gt;</code></strong> element.'
116
+ );
117
+ }
118
+ else if (isStyleAttribute(attrName)) {
119
+ this.log.push(
120
+ 'Found <span class="style-attribute">style attribute</span> on <strong><code>&lt;' +
121
+ tag + '&gt;</code></strong> element.'
122
+ );
123
+ }
124
+ else if (isInaccessibleAttribute(attrName, attrValue)) {
125
+ this.log.push(
126
+ 'Found <span class="inaccessible-attribute">inaccessible attribute</span> ' +
127
+ '(on <strong><code>&lt;' + tag + '&gt;</code></strong> element).'
128
+ );
129
+ }
130
+ };
105
131
 
106
- Lint.prototype.testAttribute = function(tag, attrName, attrValue) {
107
- if (isEventAttribute(attrName)) {
108
- this.log.push(
109
- 'Found <span class="event-attribute">event attribute</span> (<strong>' +
110
- attrName + '</strong>) on <strong><code>&lt;' + tag + '&gt;</code></strong> element.'
111
- );
112
- }
113
- else if (isDeprecatedAttribute(tag, attrName)) {
114
- this.log.push(
115
- 'Found <span class="deprecated-attribute">deprecated</span> <strong>' +
116
- attrName + '</strong> attribute on <strong><code>&lt;' + tag + '&gt;</code></strong> element.'
117
- );
118
- }
119
- else if (isStyleAttribute(attrName)) {
120
- this.log.push(
121
- 'Found <span class="style-attribute">style attribute</span> on <strong><code>&lt;' +
122
- tag + '&gt;</code></strong> element.'
123
- );
124
- }
125
- else if (isInaccessibleAttribute(attrName, attrValue)) {
126
- this.log.push(
127
- 'Found <span class="inaccessible-attribute">inaccessible attribute</span> ' +
128
- '(on <strong><code>&lt;' + tag + '&gt;</code></strong> element).'
129
- );
130
- }
131
- };
132
+ Lint.prototype.testChars = function(chars) {
133
+ this._lastElement = '';
134
+ if (/(&nbsp;\s*){2,}/.test(chars)) {
135
+ this.log.push('Found repeating <strong><code>&amp;nbsp;</code></strong> sequence. Try replacing it with styling.');
136
+ }
137
+ };
132
138
 
133
- Lint.prototype.testChars = function(chars) {
134
- this._lastElement = '';
135
- if (/(&nbsp;\s*){2,}/.test(chars)) {
136
- this.log.push('Found repeating <strong><code>&amp;nbsp;</code></strong> sequence. Try replacing it with styling.');
137
- }
138
- };
139
+ Lint.prototype.test = function(tag, attrName, attrValue) {
140
+ this.testElement(tag);
141
+ this.testAttribute(tag, attrName, attrValue);
142
+ };
139
143
 
140
- Lint.prototype.test = function(tag, attrName, attrValue) {
141
- this.testElement(tag);
142
- this.testAttribute(tag, attrName, attrValue);
143
- };
144
+ Lint.prototype.populate = function(writeToElement) {
145
+ if (this._isElementRepeated) {
146
+ this._reportRepeatingElement();
147
+ }
144
148
 
145
- Lint.prototype.populate = function(writeToElement) {
146
- if (this._isElementRepeated) {
147
- this._reportRepeatingElement();
149
+ if (this.log.length) {
150
+ if (writeToElement) {
151
+ writeToElement.innerHTML = '<ol><li>' + this.log.join('<li>') + '</ol>';
148
152
  }
153
+ else {
154
+ var output = ' - ' +
155
+ this.log.join('\n - ')
156
+ .replace(/(<([^>]+)>)/ig, '')
157
+ .replace(/&lt;/g, '<')
158
+ .replace(/&gt;/g, '>');
149
159
 
150
- if (this.log.length) {
151
- if (writeToElement) {
152
- writeToElement.innerHTML = '<ol><li>' + this.log.join('<li>') + '</ol>';
153
- }
154
- else {
155
- var output = ' - ' +
156
- this.log.join('\n - ')
157
- .replace(/(<([^>]+)>)/ig, '')
158
- .replace(/&lt;/g, '<')
159
- .replace(/&gt;/g, '>');
160
-
161
- console.log(output);
162
- }
160
+ console.log(output);
163
161
  }
164
- };
165
-
166
- global.HTMLLint = Lint;
162
+ }
163
+ };
167
164
 
168
- })(typeof exports === 'undefined' ? this : exports);
165
+ exports.HTMLLint = Lint;