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/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-2013 Juriy "kangax" Zaytsev
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 (/^(?:big|small|hr|blink|marquee)$/).test(tag);
12
+ return /^(?:big|small|hr|blink|marquee)$/.test(tag);
13
13
  }
14
14
  function isDeprecatedElement(tag) {
15
- return (/^(?:applet|basefont|center|dir|font|isindex|strike)$/).test(tag);
15
+ return /^(?:applet|basefont|center|dir|font|isindex|strike)$/.test(tag);
16
16
  }
17
17
  function isEventAttribute(attrName) {
18
- return (/^on[a-z]+/).test(attrName);
18
+ return /^on[a-z]+/.test(attrName);
19
19
  }
20
20
  function isStyleAttribute(attrName) {
21
- return (attrName.toLowerCase() === 'style');
21
+ return attrName.toLowerCase() === 'style';
22
22
  }
23
23
  function isDeprecatedAttribute(tag, attrName) {
24
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))
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>&lt;' +
@@ -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>&lt;' + tag + '&gt;</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
- if (this.log.length) {
150
- if (writeToElement) {
151
- writeToElement.innerHTML = '<ol><li>' + this.log.join('<li>') + '</ol>';
152
- }
153
- else {
154
- var output = ' - ' +
155
- this.log.join('\n - ')
156
- .replace(/(<([^>]+)>)/ig, '')
157
- .replace(/&lt;/g, '<')
158
- .replace(/&gt;/g, '>');
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(/&lt;/g, '<').replace(/&gt;/g, '>'));
162
174
  }
163
175
  };
164
176