UNPKG

4.97 kBJavaScriptView Raw
1var options = {};
2
3function setup(opt) {
4 options = {
5 'attr-to-remove': [
6 'align',
7 'valign',
8 'bgcolor',
9 'color',
10 'width',
11 'height',
12 'border',
13 'cellpadding',
14 'cellspacing'
15 ],
16 'block-tags': [
17 'div',
18 'p',
19 'table',
20 'tr',
21 'td',
22 'blockquote',
23 'hr'
24 ],
25 'break-after-br': true,
26 'close-empty-tags': false,
27 'empty-tags': [
28 'br',
29 'hr',
30 'img'
31 ],
32 'indent': ' ',
33 'pretty': true,
34 'remove-comments': false,
35 'tags-to-remove': [
36 'font'
37 ]
38 };
39
40 if (!opt) {
41 return;
42 }
43
44 options['attr-to-remove'] = opt['attr-to-remove'] || options['attr-to-remove'];
45 options['block-tags'] = opt['block-tags'] || options['block-tags'];
46 options['break-after-br'] = opt['break-after-br'] === false ? false : true;
47 options['close-empty-tags'] = opt['close-empty-tags'] === true ? true : false;
48 options['empty-tags'] = opt['empty-tags'] || options['empty-tags'];
49 options['indent'] = opt['indent'] || options['indent'];
50 options['pretty'] = opt['pretty'] === false ? false : true;
51 options['remove-comments'] = opt['remove-comments'] === true ? true : false;
52 options['tags-to-remove'] = opt['tags-to-remove'] || options['tags-to-remove'];
53
54 if (opt['add-attr-to-remove']) {
55 options['attr-to-remove'] = options['attr-to-remove'].concat(opt['add-attr-to-remove']);
56 }
57
58 if (opt['add-block-tags']) {
59 options['block-tags'] = options['block-tags'].concat(opt['add-block-tags']);
60 }
61
62 if (opt['add-empty-tags']) {
63 options['empty-tags'] = options['empty-tags'].concat(opt['add-empty-tags']);
64 }
65
66 if (opt['add-tags-to-remove']) {
67 options['tags-to-remove'] = options['tags-to-remove'].concat(opt['add-tags-to-remove']);
68 }
69}
70
71function replaceWhiteSpace(html) {
72 return html.replace(/\s/g, ' ');
73}
74
75function removeExtraSpaces(html) {
76 return html.replace(/ {2,}/g, ' ');
77}
78
79function closeEmptyTag(tag) {
80 return tag.replace(/ ?\/?>/, '/>');
81}
82
83function removeTrailingSlash(tag) {
84 return tag.replace(/ ?\/>/, '>');
85}
86
87function cleanAttributes(tag) {
88 return tag.replace(/ (\w+)=['"].+?['"]/g, function (attribute, attributeName) {
89 if (options['attr-to-remove'].indexOf(attributeName) > -1) {
90 return '';
91 }
92
93 return attribute;
94 });
95}
96
97function cleanTags(html) {
98 return html.replace(/<\/?(\w+).*?>/g, function (tag, tagName) {
99 tag = tag.toLowerCase();
100 tagName = tagName.toLowerCase();
101
102 if (options['tags-to-remove'].indexOf(tagName) > -1) {
103 return '';
104 }
105
106 if (options['empty-tags'].indexOf(tagName) > -1) {
107 if (options['close-empty-tags']) {
108 tag = closeEmptyTag(tag);
109 } else {
110 tag = removeTrailingSlash(tag);
111 }
112 }
113
114 tag = cleanAttributes(tag);
115
116 return tag;
117 });
118}
119
120function removeComments(html) {
121 return html.replace(/<!--.*?-->/g, '');
122}
123
124function addLineBreaks(html) {
125 return html.replace(/<\/?(\w+).*?>/g, function (tag, tagName) {
126 if (options['block-tags'].indexOf(tagName) > -1) {
127 return '\n' + tag + '\n';
128 }
129
130 if (tagName == 'br' && options['break-after-br']) {
131 return tag + '\n';
132 }
133
134 return tag;
135 });
136}
137
138function removeBlankLines(html) {
139 return html.replace(/\s{2,}/g, '\n');
140}
141
142function indentLine(line, indentLevel) {
143 var indent = '';
144
145 for (var i = 0; i < indentLevel; i++) {
146 indent += options['indent'];
147 }
148
149 return indent + line;
150}
151
152function indent(html) {
153 var indentLevel = 0;
154
155 return html.replace(/.*\n/g, function (line) {
156 var match = line.match(/<\/?(\w+).*?>/);
157
158 if (!match) {
159 return indentLine(line, indentLevel);
160 }
161
162 var tag = match[0],
163 tagName = match[1];
164
165 if (options['block-tags'].indexOf(tagName) > -1) {
166 if (tag.indexOf('</') === 0) {
167 indentLevel--;
168 line = indentLine(line, indentLevel);
169 } else {
170 line = indentLine(line, indentLevel);
171 indentLevel++;
172 }
173
174 return line;
175 }
176
177 return indentLine(line, indentLevel);
178 });
179}
180
181function clean(html, opt) {
182 setup(opt);
183
184 html = replaceWhiteSpace(html);
185 html = removeExtraSpaces(html);
186 html = cleanTags(html);
187
188 if (options['remove-comments']) {
189 html = removeComments(html);
190 }
191
192 if (options['pretty']) {
193 html = addLineBreaks(html);
194 html = removeBlankLines(html);
195 html = indent(html);
196 }
197
198 return html.trim();
199}
200
201module.exports = {
202 clean: clean
203};