-
Notifications
You must be signed in to change notification settings - Fork 114
Expand file tree
/
Copy pathapply-conditions.js
More file actions
118 lines (97 loc) · 2.75 KB
/
apply-conditions.js
File metadata and controls
118 lines (97 loc) · 2.75 KB
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
"use strict"
const base64EncodedConditionalImport = require("./base64-encoded-import")
module.exports = function applyConditions(bundle, atRule) {
const firstImportStatementIndex = bundle.findIndex(
stmt => stmt.type === "import",
)
const lastImportStatementIndex = bundle.findLastIndex(
stmt => stmt.type === "import",
)
bundle.forEach((stmt, index) => {
if (stmt.type === "charset" || stmt.type === "warning") {
return
}
if (
stmt.type === "layer" &&
((index < lastImportStatementIndex && stmt.conditions?.length) ||
(index > firstImportStatementIndex && index < lastImportStatementIndex))
) {
stmt.type = "import"
stmt.node = stmt.node.clone({
name: "import",
params: base64EncodedConditionalImport(
`'data:text/css;base64,${Buffer.from(stmt.node.toString()).toString(
"base64",
)}'`,
stmt.conditions,
),
})
return
}
if (!stmt.conditions?.length) {
return
}
if (stmt.type === "import") {
stmt.node.params = base64EncodedConditionalImport(
stmt.fullUri,
stmt.conditions,
)
return
}
let nodes
let parent
if (stmt.type === "layer") {
nodes = [stmt.node]
parent = stmt.node.parent
} else {
nodes = stmt.nodes
parent = nodes[0].parent
}
const atRules = []
// Convert conditions to at-rules
for (const condition of stmt.conditions) {
if (typeof condition.media !== "undefined") {
const mediaNode = atRule({
name: "media",
params: condition.media,
source: parent.source,
})
atRules.push(mediaNode)
}
if (typeof condition.supports !== "undefined") {
const supportsNode = atRule({
name: "supports",
params: `(${condition.supports})`,
source: parent.source,
})
atRules.push(supportsNode)
}
if (typeof condition.layer !== "undefined") {
const layerNode = atRule({
name: "layer",
params: condition.layer,
source: parent.source,
})
atRules.push(layerNode)
}
}
// Add nodes to AST
const outerAtRule = atRules.shift()
const innerAtRule = atRules.reduce((previous, next) => {
previous.append(next)
return next
}, outerAtRule)
parent.insertBefore(nodes[0], outerAtRule)
// remove nodes
nodes.forEach(node => {
node.parent = undefined
})
// better output
nodes[0].raws.before = nodes[0].raws.before || "\n"
// wrap new rules with media query and/or layer at rule
innerAtRule.append(nodes)
stmt.type = "nodes"
stmt.nodes = [outerAtRule]
delete stmt.node
})
}