Skip to content

Commit 3612ef5

Browse files
committed
handle angle brackets in html attrs. close #37.
1 parent 29d6ff5 commit 3612ef5

File tree

7 files changed

+71
-53
lines changed

7 files changed

+71
-53
lines changed

dist/dropcss.cjs.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,16 @@ var VOIDS = new Set("area base br col command embed hr img input keygen link met
2121

2222
// doctype, comments, meta, style, link & script tags. TODO: CDATA
2323
var NASTIES = /<!doctype[^>]*>|<!--[\s\S]*?-->|<script[^>]*>[\s\S]*?<\/script>|<style[^>]*>[\s\S]*?<\/style>|<link[^>]*>|<meta[^>]*>/gmi;
24-
var RE_ATTRS = /([\w-]+)(?:="([^"]*)"|='([^']*)'|=(\S+))?/gm;
2524
var RE = {
26-
TAG_HEAD: /\s*<([\w-]+)(?:\s*([^>]*))?>\s*/myi,
25+
NAME: /\s*<([\w-]+)\s*/myi,
26+
ATTR: /\s*([\w-]+)(?:="([^"]*)"|='([^']*)'|=(\S+))?\s*/myi,
27+
TAIL: /\s*(\/?>)\s*/myi,
2728
TEXT: /\s*[^<]*/my,
28-
TAG_CLOSE: /\s*<\/[\w-]+>\s*/myi,
29+
CLOSE: /\s*<\/[\w-]+>\s*/myi,
2930
};
3031

3132
function tokenize(html) {
32-
var pos = 0, m, tokens = [];
33+
var pos = 0, m, m2, tokens = [];
3334

3435
function syncPos(re) {
3536
pos = re.lastIndex;
@@ -38,34 +39,39 @@ function tokenize(html) {
3839
}
3940

4041
function next() {
41-
m = RE.TAG_CLOSE.exec(html);
42+
m = RE.CLOSE.exec(html);
4243

4344
if (m != null) {
44-
syncPos(RE.TAG_CLOSE);
45+
syncPos(RE.CLOSE);
4546
tokens.push(TAG_CLOSE);
4647
return;
4748
}
4849

49-
m = RE.TAG_HEAD.exec(html);
50+
m = RE.NAME.exec(html);
5051

5152
if (m != null) {
52-
syncPos(RE.TAG_HEAD);
53+
syncPos(RE.NAME);
5354
var tag = m[1];
5455
tokens.push(TAG_OPEN, tag);
5556

56-
var attrs = m[2];
57+
var attrMap;
5758

58-
if (attrs != null) {
59-
var attrMap = new Map();
60-
var m2;
61-
while (m2 = RE_ATTRS.exec(attrs))
62-
{ attrMap.set(m2[1], (m2[2] || m2[3] || m2[4] || '').trim()); }
63-
tokens.push(ATTRS, attrMap);
59+
while (m2 = RE.ATTR.exec(html)) {
60+
syncPos(RE.ATTR);
61+
attrMap = attrMap || new Map();
62+
attrMap.set(m2[1], (m2[2] || m2[3] || m2[4] || '').trim());
6463
}
6564

66-
if (VOIDS.has(tag) || attrs && attrs.endsWith("/"))
65+
if (attrMap)
66+
{ tokens.push(ATTRS, attrMap); }
67+
68+
m2 = RE.TAIL.exec(html);
69+
70+
if (VOIDS.has(tag) || m2[1] == "/>")
6771
{ tokens.push(TAG_CLOSE); }
6872

73+
syncPos(RE.TAIL);
74+
6975
return;
7076
}
7177

dist/dropcss.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,16 @@
2525

2626
// doctype, comments, meta, style, link & script tags. TODO: CDATA
2727
var NASTIES = /<!doctype[^>]*>|<!--[\s\S]*?-->|<script[^>]*>[\s\S]*?<\/script>|<style[^>]*>[\s\S]*?<\/style>|<link[^>]*>|<meta[^>]*>/gmi;
28-
var RE_ATTRS = /([\w-]+)(?:="([^"]*)"|='([^']*)'|=(\S+))?/gm;
2928
var RE = {
30-
TAG_HEAD: /\s*<([\w-]+)(?:\s*([^>]*))?>\s*/myi,
29+
NAME: /\s*<([\w-]+)\s*/myi,
30+
ATTR: /\s*([\w-]+)(?:="([^"]*)"|='([^']*)'|=(\S+))?\s*/myi,
31+
TAIL: /\s*(\/?>)\s*/myi,
3132
TEXT: /\s*[^<]*/my,
32-
TAG_CLOSE: /\s*<\/[\w-]+>\s*/myi,
33+
CLOSE: /\s*<\/[\w-]+>\s*/myi,
3334
};
3435

3536
function tokenize(html) {
36-
var pos = 0, m, tokens = [];
37+
var pos = 0, m, m2, tokens = [];
3738

3839
function syncPos(re) {
3940
pos = re.lastIndex;
@@ -42,34 +43,39 @@
4243
}
4344

4445
function next() {
45-
m = RE.TAG_CLOSE.exec(html);
46+
m = RE.CLOSE.exec(html);
4647

4748
if (m != null) {
48-
syncPos(RE.TAG_CLOSE);
49+
syncPos(RE.CLOSE);
4950
tokens.push(TAG_CLOSE);
5051
return;
5152
}
5253

53-
m = RE.TAG_HEAD.exec(html);
54+
m = RE.NAME.exec(html);
5455

5556
if (m != null) {
56-
syncPos(RE.TAG_HEAD);
57+
syncPos(RE.NAME);
5758
var tag = m[1];
5859
tokens.push(TAG_OPEN, tag);
5960

60-
var attrs = m[2];
61+
var attrMap;
6162

62-
if (attrs != null) {
63-
var attrMap = new Map();
64-
var m2;
65-
while (m2 = RE_ATTRS.exec(attrs))
66-
{ attrMap.set(m2[1], (m2[2] || m2[3] || m2[4] || '').trim()); }
67-
tokens.push(ATTRS, attrMap);
63+
while (m2 = RE.ATTR.exec(html)) {
64+
syncPos(RE.ATTR);
65+
attrMap = attrMap || new Map();
66+
attrMap.set(m2[1], (m2[2] || m2[3] || m2[4] || '').trim());
6867
}
6968

70-
if (VOIDS.has(tag) || attrs && attrs.endsWith("/"))
69+
if (attrMap)
70+
{ tokens.push(ATTRS, attrMap); }
71+
72+
m2 = RE.TAIL.exec(html);
73+
74+
if (VOIDS.has(tag) || m2[1] == "/>")
7175
{ tokens.push(TAG_CLOSE); }
7276

77+
syncPos(RE.TAIL);
78+
7379
return;
7480
}
7581

dist/dropcss.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"devDependencies": {
2828
"mocha": "^6.2.0",
2929
"nyc": "^14.1.1",
30-
"rollup": "^1.17.0",
30+
"rollup": "^1.19.4",
3131
"rollup-plugin-buble": "^0.19.8",
3232
"rollup-plugin-cjs-es": "^0.9.0",
3333
"rollup-plugin-terser": "^5.1.1"

src/html.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@ const VOIDS = new Set("area base br col command embed hr img input keygen link m
1010

1111
// doctype, comments, meta, style, link & script tags. TODO: CDATA
1212
const NASTIES = /<!doctype[^>]*>|<!--[\s\S]*?-->|<script[^>]*>[\s\S]*?<\/script>|<style[^>]*>[\s\S]*?<\/style>|<link[^>]*>|<meta[^>]*>/gmi;
13-
const RE_ATTRS = /([\w-]+)(?:="([^"]*)"|='([^']*)'|=(\S+))?/gm;
1413
const RE = {
15-
TAG_HEAD: /\s*<([\w-]+)(?:\s*([^>]*))?>\s*/myi,
14+
NAME: /\s*<([\w-]+)\s*/myi,
15+
ATTR: /\s*([\w-]+)(?:="([^"]*)"|='([^']*)'|=(\S+))?\s*/myi,
16+
TAIL: /\s*(\/?>)\s*/myi,
1617
TEXT: /\s*[^<]*/my,
17-
TAG_CLOSE: /\s*<\/[\w-]+>\s*/myi,
18+
CLOSE: /\s*<\/[\w-]+>\s*/myi,
1819
};
1920

2021
function tokenize(html) {
21-
let pos = 0, m, tokens = [];
22+
let pos = 0, m, m2, tokens = [];
2223

2324
function syncPos(re) {
2425
pos = re.lastIndex;
@@ -27,34 +28,39 @@ function tokenize(html) {
2728
}
2829

2930
function next() {
30-
m = RE.TAG_CLOSE.exec(html);
31+
m = RE.CLOSE.exec(html);
3132

3233
if (m != null) {
33-
syncPos(RE.TAG_CLOSE);
34+
syncPos(RE.CLOSE);
3435
tokens.push(TAG_CLOSE);
3536
return;
3637
}
3738

38-
m = RE.TAG_HEAD.exec(html);
39+
m = RE.NAME.exec(html);
3940

4041
if (m != null) {
41-
syncPos(RE.TAG_HEAD);
42+
syncPos(RE.NAME);
4243
let tag = m[1];
4344
tokens.push(TAG_OPEN, tag);
4445

45-
let attrs = m[2];
46+
let attrMap;
4647

47-
if (attrs != null) {
48-
let attrMap = new Map();
49-
let m2;
50-
while (m2 = RE_ATTRS.exec(attrs))
51-
attrMap.set(m2[1], (m2[2] || m2[3] || m2[4] || '').trim());
52-
tokens.push(ATTRS, attrMap);
48+
while (m2 = RE.ATTR.exec(html)) {
49+
syncPos(RE.ATTR);
50+
attrMap = attrMap || new Map();
51+
attrMap.set(m2[1], (m2[2] || m2[3] || m2[4] || '').trim());
5352
}
5453

55-
if (VOIDS.has(tag) || attrs && attrs.endsWith("/"))
54+
if (attrMap)
55+
tokens.push(ATTRS, attrMap);
56+
57+
m2 = RE.TAIL.exec(html);
58+
59+
if (VOIDS.has(tag) || m2[1] == "/>")
5660
tokens.push(TAG_CLOSE);
5761

62+
syncPos(RE.TAIL);
63+
5864
return;
5965
}
6066

test/bench/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"dependencies": {
1010
"purgecss": "^1.3.0",
1111
"purify-css": "^1.2.5",
12-
"uncss": "^0.16.2"
12+
"uncss": "^0.17.0"
1313
},
1414
"author": "Leon Sorokin <leeoniya@gmail.com>",
1515
"license": "MIT"

test/coverage.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
-------------|----------|----------|----------|----------|-------------------|
22
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
33
-------------|----------|----------|----------|----------|-------------------|
4-
All files | 96.3 | 86.43 | 96.55 | 96.32 | |
4+
All files | 96.3 | 86.49 | 96.55 | 96.33 | |
55
css.js | 97.22 | 90.48 | 100 | 97.12 | 133,134,167 |
66
dropcss.js | 95.35 | 83.33 | 85.71 | 96.2 | 28,29,102 |
77
env.js | 100 | 100 | 100 | 100 | |
88
err.js | 50 | 100 | 0 | 50 | 2 |
99
find.js | 99.19 | 95.24 | 100 | 99.18 | 163 |
10-
html.js | 97.8 | 92.31 | 100 | 97.7 | 73,117 |
10+
html.js | 97.83 | 92.5 | 100 | 97.73 | 79,123 |
1111
nth.js | 62.5 | 60 | 100 | 62.5 | 34,38,40,49,54,56 |
1212
postproc.js | 98.72 | 75 | 100 | 98.61 | 62 |
1313
sel.js | 95.08 | 84.62 | 100 | 95.08 | 111,116,123 |

0 commit comments

Comments
 (0)