1 | let Prefixer = require('./prefixer')
|
2 | let Browsers = require('./browsers')
|
3 | let utils = require('./utils')
|
4 |
|
5 | class Declaration extends Prefixer {
|
6 | |
7 |
|
8 |
|
9 | check() {
|
10 | return true
|
11 | }
|
12 |
|
13 | |
14 |
|
15 |
|
16 | prefixed(prop, prefix) {
|
17 | return prefix + prop
|
18 | }
|
19 |
|
20 | |
21 |
|
22 |
|
23 | normalize(prop) {
|
24 | return prop
|
25 | }
|
26 |
|
27 | |
28 |
|
29 |
|
30 | otherPrefixes(value, prefix) {
|
31 | for (let other of Browsers.prefixes()) {
|
32 | if (other === prefix) {
|
33 | continue
|
34 | }
|
35 | if (value.includes(other)) {
|
36 | return true
|
37 | }
|
38 | }
|
39 | return false
|
40 | }
|
41 |
|
42 | |
43 |
|
44 |
|
45 | set(decl, prefix) {
|
46 | decl.prop = this.prefixed(decl.prop, prefix)
|
47 | return decl
|
48 | }
|
49 |
|
50 | |
51 |
|
52 |
|
53 | needCascade(decl) {
|
54 | if (!decl._autoprefixerCascade) {
|
55 | decl._autoprefixerCascade =
|
56 | this.all.options.cascade !== false && decl.raw('before').includes('\n')
|
57 | }
|
58 | return decl._autoprefixerCascade
|
59 | }
|
60 |
|
61 | |
62 |
|
63 |
|
64 | maxPrefixed(prefixes, decl) {
|
65 | if (decl._autoprefixerMax) {
|
66 | return decl._autoprefixerMax
|
67 | }
|
68 |
|
69 | let max = 0
|
70 | for (let prefix of prefixes) {
|
71 | prefix = utils.removeNote(prefix)
|
72 | if (prefix.length > max) {
|
73 | max = prefix.length
|
74 | }
|
75 | }
|
76 | decl._autoprefixerMax = max
|
77 |
|
78 | return decl._autoprefixerMax
|
79 | }
|
80 |
|
81 | |
82 |
|
83 |
|
84 | calcBefore(prefixes, decl, prefix = '') {
|
85 | let max = this.maxPrefixed(prefixes, decl)
|
86 | let diff = max - utils.removeNote(prefix).length
|
87 |
|
88 | let before = decl.raw('before')
|
89 | if (diff > 0) {
|
90 | before += Array(diff).fill(' ').join('')
|
91 | }
|
92 |
|
93 | return before
|
94 | }
|
95 |
|
96 | |
97 |
|
98 |
|
99 | restoreBefore(decl) {
|
100 | let lines = decl.raw('before').split('\n')
|
101 | let min = lines[lines.length - 1]
|
102 |
|
103 | this.all.group(decl).up(prefixed => {
|
104 | let array = prefixed.raw('before').split('\n')
|
105 | let last = array[array.length - 1]
|
106 | if (last.length < min.length) {
|
107 | min = last
|
108 | }
|
109 | })
|
110 |
|
111 | lines[lines.length - 1] = min
|
112 | decl.raws.before = lines.join('\n')
|
113 | }
|
114 |
|
115 | |
116 |
|
117 |
|
118 | insert(decl, prefix, prefixes) {
|
119 | let cloned = this.set(this.clone(decl), prefix)
|
120 | if (!cloned) return undefined
|
121 |
|
122 | let already = decl.parent.some(
|
123 | i => i.prop === cloned.prop && i.value === cloned.value
|
124 | )
|
125 | if (already) {
|
126 | return undefined
|
127 | }
|
128 |
|
129 | if (this.needCascade(decl)) {
|
130 | cloned.raws.before = this.calcBefore(prefixes, decl, prefix)
|
131 | }
|
132 | return decl.parent.insertBefore(decl, cloned)
|
133 | }
|
134 |
|
135 | |
136 |
|
137 |
|
138 | isAlready(decl, prefixed) {
|
139 | let already = this.all.group(decl).up(i => i.prop === prefixed)
|
140 | if (!already) {
|
141 | already = this.all.group(decl).down(i => i.prop === prefixed)
|
142 | }
|
143 | return already
|
144 | }
|
145 |
|
146 | |
147 |
|
148 |
|
149 | add(decl, prefix, prefixes, result) {
|
150 | let prefixed = this.prefixed(decl.prop, prefix)
|
151 | if (
|
152 | this.isAlready(decl, prefixed) ||
|
153 | this.otherPrefixes(decl.value, prefix)
|
154 | ) {
|
155 | return undefined
|
156 | }
|
157 | return this.insert(decl, prefix, prefixes, result)
|
158 | }
|
159 |
|
160 | |
161 |
|
162 |
|
163 | process(decl, result) {
|
164 | if (!this.needCascade(decl)) {
|
165 | super.process(decl, result)
|
166 | return
|
167 | }
|
168 |
|
169 | let prefixes = super.process(decl, result)
|
170 |
|
171 | if (!prefixes || !prefixes.length) {
|
172 | return
|
173 | }
|
174 |
|
175 | this.restoreBefore(decl)
|
176 | decl.raws.before = this.calcBefore(prefixes, decl)
|
177 | }
|
178 |
|
179 | |
180 |
|
181 |
|
182 | old(prop, prefix) {
|
183 | return [this.prefixed(prop, prefix)]
|
184 | }
|
185 | }
|
186 |
|
187 | module.exports = Declaration
|