@projectwallace/css-analyzer 5.0.0-alpha.1 → 5.0.2
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/dist/analyzer.cjs +1 -1
- package/dist/analyzer.cjs.map +1 -1
- package/dist/analyzer.modern.js +2 -0
- package/dist/analyzer.modern.js.map +1 -0
- package/dist/analyzer.module.js +1 -1
- package/dist/analyzer.module.js.map +1 -1
- package/dist/analyzer.umd.js +1 -1
- package/dist/analyzer.umd.js.map +1 -1
- package/package.json +10 -10
- package/dist/analyzer.js +0 -2
- package/dist/analyzer.js.map +0 -1
- package/src/aggregate-collection.js +0 -113
- package/src/aggregate-collection.test.js +0 -47
- package/src/atrules/atrules.js +0 -76
- package/src/atrules/atrules.test.js +0 -289
- package/src/context-collection.js +0 -36
- package/src/countable-collection.js +0 -46
- package/src/declarations/declarations.js +0 -46
- package/src/declarations/declarations.test.js +0 -113
- package/src/index.js +0 -259
- package/src/index.test.js +0 -60
- package/src/properties/properties.js +0 -48
- package/src/properties/properties.test.js +0 -138
- package/src/rules/rules.js +0 -57
- package/src/rules/rules.test.js +0 -247
- package/src/selectors/complexity.test.js +0 -123
- package/src/selectors/selectors.js +0 -122
- package/src/selectors/selectors.test.js +0 -189
- package/src/selectors/specificity.js +0 -201
- package/src/selectors/specificity.test.js +0 -247
- package/src/smoke.test.js +0 -39
- package/src/stylesheet/stylesheet.test.js +0 -88
- package/src/values/animations.js +0 -53
- package/src/values/animations.test.js +0 -154
- package/src/values/box-shadows.test.js +0 -82
- package/src/values/colors.js +0 -192
- package/src/values/colors.test.js +0 -804
- package/src/values/font-families.js +0 -98
- package/src/values/font-families.test.js +0 -119
- package/src/values/font-sizes.js +0 -92
- package/src/values/font-sizes.test.js +0 -120
- package/src/values/text-shadows.test.js +0 -93
- package/src/values/units.test.js +0 -72
- package/src/values/values.js +0 -30
- package/src/values/vendor-prefix.js +0 -45
- package/src/values/vendor-prefix.test.js +0 -64
- package/src/values/z-index.test.js +0 -54
- package/src/vendor-prefix.js +0 -16
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import * as csstree from 'css-tree'
|
|
2
|
-
import { CountableCollection } from '../countable-collection.js'
|
|
3
|
-
|
|
4
|
-
const systemKeywords = {
|
|
5
|
-
// Global CSS keywords
|
|
6
|
-
'inherit': 1,
|
|
7
|
-
'initial': 1,
|
|
8
|
-
'unset': 1,
|
|
9
|
-
'revert': 1,
|
|
10
|
-
|
|
11
|
-
// System font keywords
|
|
12
|
-
'caption': 1,
|
|
13
|
-
'icon': 1,
|
|
14
|
-
'menu': 1,
|
|
15
|
-
'message-box': 1,
|
|
16
|
-
'small-caption': 1,
|
|
17
|
-
'status-bar': 1,
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const keywordDisallowList = {
|
|
21
|
-
// font-weight, font-stretch, font-style
|
|
22
|
-
'normal': 1,
|
|
23
|
-
|
|
24
|
-
// font-size keywords
|
|
25
|
-
'xx-small': 1,
|
|
26
|
-
'x-small': 1,
|
|
27
|
-
'small': 1,
|
|
28
|
-
'medium': 1,
|
|
29
|
-
'large': 1,
|
|
30
|
-
'x-large': 1,
|
|
31
|
-
'xx-large': 1,
|
|
32
|
-
'larger': 1,
|
|
33
|
-
'smaller': 1,
|
|
34
|
-
|
|
35
|
-
// font-weight keywords
|
|
36
|
-
'bold': 1,
|
|
37
|
-
'bolder': 1,
|
|
38
|
-
'lighter': 1,
|
|
39
|
-
|
|
40
|
-
// font-stretch keywords
|
|
41
|
-
'ultra-condensed': 1,
|
|
42
|
-
'extra-condensed': 1,
|
|
43
|
-
'condensed': 1,
|
|
44
|
-
'semi-condensed': 1,
|
|
45
|
-
'semi-expanded': 1,
|
|
46
|
-
'expanded': 1,
|
|
47
|
-
'extra-expanded': 1,
|
|
48
|
-
'ultra-expanded': 1,
|
|
49
|
-
|
|
50
|
-
// font-style keywords
|
|
51
|
-
'italic': 1,
|
|
52
|
-
'oblique': 1,
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const COMMA = 44 // ','.charCodeAt(0) === 44
|
|
56
|
-
|
|
57
|
-
const analyzeFontFamilies = ({ fontValues, fontFamilyValues }) => {
|
|
58
|
-
const all = new CountableCollection(fontFamilyValues)
|
|
59
|
-
|
|
60
|
-
for (let index = 0; index < fontValues.length; index++) {
|
|
61
|
-
const value = fontValues[index]
|
|
62
|
-
|
|
63
|
-
// Avoid tree traversal as soon as possible
|
|
64
|
-
const firstChild = value.children.first
|
|
65
|
-
|
|
66
|
-
if (firstChild.type === 'Identifier' && systemKeywords[firstChild.name]) {
|
|
67
|
-
continue
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const parts = []
|
|
71
|
-
|
|
72
|
-
csstree.walk(value, {
|
|
73
|
-
reverse: true,
|
|
74
|
-
enter: function (fontNode) {
|
|
75
|
-
if (fontNode.type === 'String') {
|
|
76
|
-
return parts.unshift(fontNode)
|
|
77
|
-
}
|
|
78
|
-
if (fontNode.type === 'Operator' && fontNode.value.charCodeAt(0) === COMMA) {
|
|
79
|
-
return parts.unshift(fontNode)
|
|
80
|
-
}
|
|
81
|
-
if (fontNode.type === 'Identifier') {
|
|
82
|
-
if (keywordDisallowList[fontNode.name]) {
|
|
83
|
-
return this.skip
|
|
84
|
-
}
|
|
85
|
-
return parts.unshift(fontNode)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
all.push(parts.map(csstree.generate).join(''))
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return all.count()
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export {
|
|
97
|
-
analyzeFontFamilies
|
|
98
|
-
}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { suite } from 'uvu';
|
|
2
|
-
import * as assert from 'uvu/assert';
|
|
3
|
-
import { analyze } from '../index.js'
|
|
4
|
-
|
|
5
|
-
const FontFamilies = suite('FontFamilies')
|
|
6
|
-
|
|
7
|
-
FontFamilies('recognizes a font-family', () => {
|
|
8
|
-
const fixture = `
|
|
9
|
-
test {
|
|
10
|
-
font-family: "Droid Sans", serif;
|
|
11
|
-
font-family: sans-serif;
|
|
12
|
-
font-family: "Arial Black", "Arial Bold", Gadget, sans-serif;
|
|
13
|
-
font-family: "Brush Script MT", cursive;
|
|
14
|
-
font-family: monospace;
|
|
15
|
-
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
|
16
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
|
17
|
-
|
|
18
|
-
/* Unrelated */
|
|
19
|
-
color: brown;
|
|
20
|
-
font-size: 12px;
|
|
21
|
-
}
|
|
22
|
-
`
|
|
23
|
-
const actual = analyze(fixture).values.fontFamilies
|
|
24
|
-
const expected = {
|
|
25
|
-
total: 7,
|
|
26
|
-
totalUnique: 7,
|
|
27
|
-
unique: {
|
|
28
|
-
'"Droid Sans", serif': 1,
|
|
29
|
-
'sans-serif': 1,
|
|
30
|
-
'"Arial Black", "Arial Bold", Gadget, sans-serif': 1,
|
|
31
|
-
'"Brush Script MT", cursive': 1,
|
|
32
|
-
'monospace': 1,
|
|
33
|
-
'Consolas, "Liberation Mono", Menlo, Courier, monospace': 1,
|
|
34
|
-
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"': 1,
|
|
35
|
-
},
|
|
36
|
-
uniquenessRatio: 7 / 7
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
assert.equal(actual, expected)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
FontFamilies('extracts the `font` shorthand', () => {
|
|
43
|
-
const fixture = `
|
|
44
|
-
test {
|
|
45
|
-
font: large "Noto Sans";
|
|
46
|
-
font: normal normal 1em/1 "Source Sans Pro", serif;
|
|
47
|
-
font: normal normal 1.2em serif;
|
|
48
|
-
font: 400 1.3em/1 serif;
|
|
49
|
-
font: 1em / 1 serif;
|
|
50
|
-
font: 1em/ 1 serif;
|
|
51
|
-
font: 1em /1 serif;
|
|
52
|
-
font: normal normal 11px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
|
53
|
-
font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
|
54
|
-
font: 0/0 a; /* As generated by some css minifiers */
|
|
55
|
-
|
|
56
|
-
/* Unrelated */
|
|
57
|
-
color: brown;
|
|
58
|
-
font-size: 12px;
|
|
59
|
-
}
|
|
60
|
-
`
|
|
61
|
-
const actual = analyze(fixture).values.fontFamilies
|
|
62
|
-
const expected = {
|
|
63
|
-
total: 10,
|
|
64
|
-
totalUnique: 6,
|
|
65
|
-
unique: {
|
|
66
|
-
'"Noto Sans"': 1,
|
|
67
|
-
'"Source Sans Pro",serif': 1,
|
|
68
|
-
'serif': 5,
|
|
69
|
-
'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"': 1,
|
|
70
|
-
'Consolas,"Liberation Mono",Menlo,Courier,monospace': 1,
|
|
71
|
-
'a': 1,
|
|
72
|
-
},
|
|
73
|
-
uniquenessRatio: 6 / 10
|
|
74
|
-
}
|
|
75
|
-
assert.equal(actual, expected)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
FontFamilies('handles system fonts', () => {
|
|
79
|
-
// Source: https://drafts.csswg.org/css-fonts-3/#font-prop
|
|
80
|
-
const fixture = `
|
|
81
|
-
test {
|
|
82
|
-
font: menu; /* use the font settings for system menus */
|
|
83
|
-
font: large menu; /* use a font family named "menu" */
|
|
84
|
-
}
|
|
85
|
-
`
|
|
86
|
-
const actual = analyze(fixture).values.fontFamilies
|
|
87
|
-
const expected = {
|
|
88
|
-
total: 1,
|
|
89
|
-
totalUnique: 1,
|
|
90
|
-
unique: {
|
|
91
|
-
'menu': 1
|
|
92
|
-
},
|
|
93
|
-
uniquenessRatio: 1 / 1
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
assert.equal(actual, expected)
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
FontFamilies('ignores keywords and global values', () => {
|
|
100
|
-
const fixture = `
|
|
101
|
-
test {
|
|
102
|
-
font: inherit;
|
|
103
|
-
font: initial;
|
|
104
|
-
font: unset;
|
|
105
|
-
font: revert;
|
|
106
|
-
}
|
|
107
|
-
`
|
|
108
|
-
const actual = analyze(fixture).values.fontFamilies
|
|
109
|
-
const expected = {
|
|
110
|
-
total: 0,
|
|
111
|
-
totalUnique: 0,
|
|
112
|
-
unique: {},
|
|
113
|
-
uniquenessRatio: 0
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
assert.equal(actual, expected)
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
FontFamilies.run()
|
package/src/values/font-sizes.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import * as csstree from 'css-tree'
|
|
2
|
-
import { CountableCollection } from '../countable-collection.js'
|
|
3
|
-
|
|
4
|
-
const sizeKeywords = {
|
|
5
|
-
'xx-small': 1,
|
|
6
|
-
'x-small': 1,
|
|
7
|
-
'small': 1,
|
|
8
|
-
'medium': 1,
|
|
9
|
-
'large': 1,
|
|
10
|
-
'x-large': 1,
|
|
11
|
-
'xx-large': 1,
|
|
12
|
-
'larger': 1,
|
|
13
|
-
'smaller': 1,
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const keywords = {
|
|
17
|
-
// Global CSS keywords
|
|
18
|
-
'inherit': 1,
|
|
19
|
-
'initial': 1,
|
|
20
|
-
'unset': 1,
|
|
21
|
-
'revert': 1,
|
|
22
|
-
|
|
23
|
-
// System font keywords
|
|
24
|
-
'caption': 1,
|
|
25
|
-
'icon': 1,
|
|
26
|
-
'menu': 1,
|
|
27
|
-
'message-box': 1,
|
|
28
|
-
'small-caption': 1,
|
|
29
|
-
'status-bar': 1,
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const ZERO = 48 // '0'.charCodeAt(0) === 48
|
|
33
|
-
const SLASH = 47 // '/'.charCodeAt(0) === 47
|
|
34
|
-
|
|
35
|
-
const analyzeFontSizes = ({ stringifyNode, fontSizeValues, fontValues }) => {
|
|
36
|
-
const all = new CountableCollection(fontSizeValues)
|
|
37
|
-
|
|
38
|
-
for (let index = 0; index < fontValues.length; index++) {
|
|
39
|
-
const fontNode = fontValues[index];
|
|
40
|
-
// Try to eliminate a keyword before we continue
|
|
41
|
-
const firstChild = fontNode.children.first
|
|
42
|
-
|
|
43
|
-
if (firstChild.type === 'Identifier' && keywords[firstChild.name]) {
|
|
44
|
-
continue
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
let operator = false
|
|
48
|
-
let size
|
|
49
|
-
|
|
50
|
-
csstree.walk(fontNode, {
|
|
51
|
-
enter: function (fontNode) {
|
|
52
|
-
switch (fontNode.type) {
|
|
53
|
-
case 'Number': {
|
|
54
|
-
// Special case for `font: 0/0 a`
|
|
55
|
-
if (fontNode.value.charCodeAt(0) === ZERO) {
|
|
56
|
-
size = '0'
|
|
57
|
-
return this.break
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
case 'Operator': {
|
|
61
|
-
if (fontNode.value.charCodeAt(0) === SLASH) {
|
|
62
|
-
operator = true
|
|
63
|
-
}
|
|
64
|
-
break
|
|
65
|
-
}
|
|
66
|
-
case 'Dimension': {
|
|
67
|
-
if (!operator) {
|
|
68
|
-
size = stringifyNode(fontNode)
|
|
69
|
-
return this.break
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
case 'Identifier': {
|
|
73
|
-
if (sizeKeywords[fontNode.name]) {
|
|
74
|
-
size = fontNode.name
|
|
75
|
-
return this.break
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
if (size) {
|
|
83
|
-
all.push(size)
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return all.count()
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export {
|
|
91
|
-
analyzeFontSizes
|
|
92
|
-
}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { suite } from 'uvu';
|
|
2
|
-
import * as assert from 'uvu/assert';
|
|
3
|
-
import { analyze } from '../index.js'
|
|
4
|
-
|
|
5
|
-
const FontSizes = suite('FontSizes')
|
|
6
|
-
|
|
7
|
-
FontSizes('recognizes a font-size', () => {
|
|
8
|
-
const fixture = `
|
|
9
|
-
test {
|
|
10
|
-
font-size: 10px;
|
|
11
|
-
font-size: small;
|
|
12
|
-
font-size: 1em;
|
|
13
|
-
font-size: calc(3vw + 1em);
|
|
14
|
-
|
|
15
|
-
/* Unrelated */
|
|
16
|
-
color: brown;
|
|
17
|
-
font-family: serif;
|
|
18
|
-
}
|
|
19
|
-
`
|
|
20
|
-
const actual = analyze(fixture).values.fontSizes
|
|
21
|
-
const expected = {
|
|
22
|
-
total: 4,
|
|
23
|
-
totalUnique: 4,
|
|
24
|
-
unique: {
|
|
25
|
-
'10px': 1,
|
|
26
|
-
'small': 1,
|
|
27
|
-
'1em': 1,
|
|
28
|
-
'calc(3vw + 1em)': 1,
|
|
29
|
-
},
|
|
30
|
-
uniquenessRatio: 4 / 4
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
assert.equal(actual, expected)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
FontSizes('extracts the `font` shorthand', () => {
|
|
37
|
-
const fixture = `
|
|
38
|
-
test {
|
|
39
|
-
font: large "Noto Sans";
|
|
40
|
-
font: normal normal 1em/1 "Source Sans Pro", serif;
|
|
41
|
-
font: normal normal 1.2em serif;
|
|
42
|
-
font: 400 1.3em/1 serif;
|
|
43
|
-
font: 1em / 1 serif;
|
|
44
|
-
font: 1em/ 1 serif;
|
|
45
|
-
font: 1em /1 serif;
|
|
46
|
-
font: 2em/1.4em serif;
|
|
47
|
-
font: normal normal 11px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
|
48
|
-
font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
|
49
|
-
font: 0/0 a; /* As generated by some css minifiers */
|
|
50
|
-
|
|
51
|
-
/* Unrelated */
|
|
52
|
-
color: brown;
|
|
53
|
-
font-family: serif;
|
|
54
|
-
}
|
|
55
|
-
`
|
|
56
|
-
const actual = analyze(fixture).values.fontSizes
|
|
57
|
-
const expected = {
|
|
58
|
-
total: 11,
|
|
59
|
-
totalUnique: 7,
|
|
60
|
-
unique: {
|
|
61
|
-
'0': 1,
|
|
62
|
-
'large': 1,
|
|
63
|
-
'1em': 4,
|
|
64
|
-
'1.2em': 1,
|
|
65
|
-
'1.3em': 1,
|
|
66
|
-
'2em': 1,
|
|
67
|
-
'11px': 2,
|
|
68
|
-
},
|
|
69
|
-
uniquenessRatio: 7 / 11
|
|
70
|
-
}
|
|
71
|
-
assert.equal(actual, expected)
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
FontSizes('handles system fonts', () => {
|
|
75
|
-
// Source: https://drafts.csswg.org/css-fonts-3/#font-prop
|
|
76
|
-
const fixture = `
|
|
77
|
-
test {
|
|
78
|
-
font: menu; /* use the font settings for system menus */
|
|
79
|
-
font: large menu; /* use a font family named "menu" */
|
|
80
|
-
}
|
|
81
|
-
`
|
|
82
|
-
const actual = analyze(fixture).values.fontSizes
|
|
83
|
-
const expected = {
|
|
84
|
-
total: 1,
|
|
85
|
-
totalUnique: 1,
|
|
86
|
-
unique: {
|
|
87
|
-
'large': 1,
|
|
88
|
-
},
|
|
89
|
-
uniquenessRatio: 1
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
assert.equal(actual, expected)
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
FontSizes('ignores keywords and global values', () => {
|
|
96
|
-
const fixture = `
|
|
97
|
-
test {
|
|
98
|
-
font: inherit;
|
|
99
|
-
font: initial;
|
|
100
|
-
font: unset;
|
|
101
|
-
font: revert;
|
|
102
|
-
|
|
103
|
-
/*TODO:font-size: inherit;
|
|
104
|
-
font-size: initial;
|
|
105
|
-
font-size: unset;
|
|
106
|
-
font-size: revert;*/
|
|
107
|
-
}
|
|
108
|
-
`
|
|
109
|
-
const actual = analyze(fixture).values.fontSizes
|
|
110
|
-
const expected = {
|
|
111
|
-
total: 0,
|
|
112
|
-
totalUnique: 0,
|
|
113
|
-
unique: {},
|
|
114
|
-
uniquenessRatio: 0
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
assert.equal(actual, expected)
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
FontSizes.run()
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { suite } from 'uvu'
|
|
2
|
-
import * as assert from 'uvu/assert'
|
|
3
|
-
import { analyze } from '../index.js'
|
|
4
|
-
|
|
5
|
-
const TextShadows = suite('TextShadows')
|
|
6
|
-
|
|
7
|
-
TextShadows('finds simple values', () => {
|
|
8
|
-
const fixture = `
|
|
9
|
-
text-shadows-simple {
|
|
10
|
-
text-shadow: 1px 1px 2px black;
|
|
11
|
-
text-shadow: #fc0 1px 0 10px;
|
|
12
|
-
text-shadow: 5px 5px #558abb;
|
|
13
|
-
text-shadow: white 2px 5px;
|
|
14
|
-
text-shadow: 5px 10px;
|
|
15
|
-
text-shadow: red 0 -2px;
|
|
16
|
-
}
|
|
17
|
-
`
|
|
18
|
-
const actual = analyze(fixture).values.textShadows
|
|
19
|
-
const expected = {
|
|
20
|
-
total: 6,
|
|
21
|
-
unique: {
|
|
22
|
-
'1px 1px 2px black': 1,
|
|
23
|
-
'#fc0 1px 0 10px': 1,
|
|
24
|
-
'5px 5px #558abb': 1,
|
|
25
|
-
'white 2px 5px': 1,
|
|
26
|
-
'5px 10px': 1,
|
|
27
|
-
'red 0 -2px': 1,
|
|
28
|
-
},
|
|
29
|
-
totalUnique: 6,
|
|
30
|
-
uniquenessRatio: 1
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
assert.equal(actual, expected)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
TextShadows('finds complex values', () => {
|
|
37
|
-
const fixture = `
|
|
38
|
-
text-shadows-complex {
|
|
39
|
-
text-shadow: 1px 1px 2px black, 0 0 1em blue, 0 0 0.2em blue;
|
|
40
|
-
}
|
|
41
|
-
`
|
|
42
|
-
const actual = analyze(fixture).values.textShadows
|
|
43
|
-
const expected = {
|
|
44
|
-
total: 1,
|
|
45
|
-
unique: {
|
|
46
|
-
'1px 1px 2px black, 0 0 1em blue, 0 0 0.2em blue': 1,
|
|
47
|
-
},
|
|
48
|
-
totalUnique: 1,
|
|
49
|
-
uniquenessRatio: 1
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
assert.equal(actual, expected)
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
TextShadows('finds vendor prefixed values', () => {
|
|
56
|
-
const fixture = `
|
|
57
|
-
text-shadows-vendor-prefixed {
|
|
58
|
-
-webkit-text-shadow: 1px 1px 2px black;
|
|
59
|
-
}
|
|
60
|
-
`
|
|
61
|
-
const actual = analyze(fixture).values.textShadows
|
|
62
|
-
const expected = {
|
|
63
|
-
total: 1,
|
|
64
|
-
unique: {
|
|
65
|
-
'1px 1px 2px black': 1,
|
|
66
|
-
},
|
|
67
|
-
totalUnique: 1,
|
|
68
|
-
uniquenessRatio: 1
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
assert.equal(actual, expected)
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
TextShadows('ignores keywords', () => {
|
|
75
|
-
const fixture = `
|
|
76
|
-
text-shadows-keyword {
|
|
77
|
-
text-shadow: initial;
|
|
78
|
-
text-shadow: none;
|
|
79
|
-
text-shadow: inherit;
|
|
80
|
-
}
|
|
81
|
-
`
|
|
82
|
-
const actual = analyze(fixture).values.textShadows
|
|
83
|
-
const expected = {
|
|
84
|
-
total: 0,
|
|
85
|
-
unique: {},
|
|
86
|
-
totalUnique: 0,
|
|
87
|
-
uniquenessRatio: 0
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
assert.equal(actual, expected)
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
TextShadows.run()
|
package/src/values/units.test.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { suite } from 'uvu'
|
|
2
|
-
import * as assert from 'uvu/assert'
|
|
3
|
-
import { analyze } from '../index.js'
|
|
4
|
-
|
|
5
|
-
const Units = suite('Units')
|
|
6
|
-
|
|
7
|
-
Units('analyzes length units', () => {
|
|
8
|
-
const fixture = `
|
|
9
|
-
test {
|
|
10
|
-
font: normal 10px/11px Arial;
|
|
11
|
-
font: 14px sans-serif;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
@media (min-width: 10em) {
|
|
15
|
-
test2 {
|
|
16
|
-
width: 12vw;
|
|
17
|
-
height: 13vmin;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
@supports (hover: hover) {
|
|
22
|
-
@media all {
|
|
23
|
-
@media screen and (max-width: 100px) {
|
|
24
|
-
line-height: 2;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
`
|
|
29
|
-
const result = analyze(fixture)
|
|
30
|
-
const actual = result.values.units
|
|
31
|
-
|
|
32
|
-
const expected = {
|
|
33
|
-
total: 5,
|
|
34
|
-
totalUnique: 3,
|
|
35
|
-
uniquenessRatio: 3 / 5,
|
|
36
|
-
unique: {
|
|
37
|
-
px: 3,
|
|
38
|
-
vw: 1,
|
|
39
|
-
vmin: 1,
|
|
40
|
-
},
|
|
41
|
-
itemsPerContext: {
|
|
42
|
-
font: {
|
|
43
|
-
total: 3,
|
|
44
|
-
totalUnique: 1,
|
|
45
|
-
uniquenessRatio: 1 / 3,
|
|
46
|
-
unique: {
|
|
47
|
-
px: 3,
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
width: {
|
|
51
|
-
total: 1,
|
|
52
|
-
totalUnique: 1,
|
|
53
|
-
uniquenessRatio: 1,
|
|
54
|
-
unique: {
|
|
55
|
-
vw: 1,
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
height: {
|
|
59
|
-
total: 1,
|
|
60
|
-
totalUnique: 1,
|
|
61
|
-
uniquenessRatio: 1,
|
|
62
|
-
unique: {
|
|
63
|
-
vmin: 1,
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
assert.equal(actual, expected)
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
Units.run()
|
package/src/values/values.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { CountableCollection } from '../countable-collection.js'
|
|
2
|
-
|
|
3
|
-
const keywords = {
|
|
4
|
-
'auto': 1,
|
|
5
|
-
'inherit': 1,
|
|
6
|
-
'initial': 1,
|
|
7
|
-
'unset': 1,
|
|
8
|
-
'revert': 1,
|
|
9
|
-
'none': 1, // for `text-shadow`
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const analyzeValues = ({ values, stringifyNode }) => {
|
|
13
|
-
const all = new CountableCollection()
|
|
14
|
-
|
|
15
|
-
for (let i = 0; i < values.length; i++) {
|
|
16
|
-
const node = values[i]
|
|
17
|
-
const firstChild = node.children.first
|
|
18
|
-
|
|
19
|
-
if (!firstChild) continue
|
|
20
|
-
if (firstChild.type === 'Identifier' && keywords[firstChild.name]) continue
|
|
21
|
-
|
|
22
|
-
all.push(stringifyNode(node))
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return all.count()
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export {
|
|
29
|
-
analyzeValues
|
|
30
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { CountableCollection } from '../countable-collection.js'
|
|
2
|
-
import { hasVendorPrefix } from '../vendor-prefix.js'
|
|
3
|
-
|
|
4
|
-
function isAstVendorPrefixed(children) {
|
|
5
|
-
children = children.toArray()
|
|
6
|
-
|
|
7
|
-
for (let index = 0; index < children.length; index++) {
|
|
8
|
-
const child = children[index];
|
|
9
|
-
|
|
10
|
-
if (child.type === 'Identifier' && child.name.length >= 3) {
|
|
11
|
-
if (hasVendorPrefix(child.name)) {
|
|
12
|
-
return true
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (child.type === 'Function') {
|
|
17
|
-
if (hasVendorPrefix(child.name)) {
|
|
18
|
-
return true
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (child.children && isAstVendorPrefixed(child.children)) {
|
|
22
|
-
return true
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return false
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const analyzeVendorPrefixes = ({ values, stringifyNode }) => {
|
|
30
|
-
const all = new CountableCollection()
|
|
31
|
-
|
|
32
|
-
for (let i = 0; i < values.length; i++) {
|
|
33
|
-
const value = values[i]
|
|
34
|
-
|
|
35
|
-
if (value.children && isAstVendorPrefixed(value.children)) {
|
|
36
|
-
all.push(stringifyNode(value))
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return all.count()
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export {
|
|
44
|
-
analyzeVendorPrefixes
|
|
45
|
-
}
|