-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathindex.coffee
71 lines (63 loc) · 2 KB
/
index.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# take gorgeous visionmedia's css utilities
parseCss = require 'css-parse'
stringifyCss = require 'css-stringify'
module.exports = (css) ->
# parse it
parsed = parseCss css
# extract and group medias and root rules
medias = {}
rootRules = []
for rule in parsed.stylesheet.rules
if rule.type is 'media'
medias[rule.media] = [] if not medias[rule.media]
medias[rule.media] = medias[rule.media].concat rule.rules
else
rootRules.push rule
# generate media rules
mediaRules = []
for media, rules of medias
rule =
type: "media"
media: media
rules: rules
# extract min-width and max-width values
if media.indexOf("min-width") isnt -1
m = media.match ///min-width:\s*(\d+)(px|em)?///
rule.minWidth = parseInt m[1] if m && m[1]
rule.unit = m[2] if m[2]
if media.indexOf("max-width") isnt -1
m = media.match ///max-width:\s*(\d+)(px|em)?///
rule.maxWidth = parseInt m[1] if m && m[1]
rule.unit = m[2] if m[2]
mediaRules.push rule
# break rules into only-min, only-max, intervals and others
onlyMinRules = mediaRules.filter (rule) ->
rule.minWidth? and not rule.maxWidth?
onlyMaxRules = mediaRules.filter (rule) ->
rule.maxWidth? and not rule.minWidth?
intervalRules = mediaRules.filter (rule) ->
rule.minWidth? and rule.maxWidth?
otherRules = mediaRules.filter (rule) ->
rule not in onlyMinRules.concat(onlyMaxRules).concat(intervalRules)
emToPxRatio = 16 # 1em = 16px
# sort media rules
onlyMinRules.sort (a, b) ->
aPxValue = a.minWidth
bPxValue = b.minWidth
aPxValue *= emToPxRatio if a.unit is 'em'
bPxValue *= emToPxRatio if b.unit is 'em'
aPxValue - bPxValue # ascending
onlyMaxRules.sort (a, b) ->
aPxValue = a.maxWidth
bPxValue = b.maxWidth
aPxValue *= emToPxRatio if a.unit is 'em'
bPxValue *= emToPxRatio if b.unit is 'em'
bPxValue - aPxValue # descending
# modify parsed AST
parsed.stylesheet.rules = rootRules
.concat(onlyMinRules)
.concat(onlyMaxRules)
.concat(intervalRules)
.concat(otherRules)
# output
stringifyCss parsed