mockaton 12.5.3 → 12.6.1
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/index.d.ts +1 -0
- package/index.js +2 -1
- package/package.json +1 -1
- package/src/client/ApiCommander.js +3 -0
- package/src/client/ApiConstants.js +4 -1
- package/src/client/IndexHtml.js +32 -0
- package/src/client/app-store.js +72 -104
- package/src/client/app-store.test.js +1 -1
- package/src/client/{styles.css → app.css} +53 -24
- package/src/client/app.js +6 -209
- package/src/client/dom-utils.js +5 -2
- package/src/client/payload-viewer.js +212 -0
- package/src/server/Api.js +20 -3
- package/src/server/MockDispatcher.js +2 -18
- package/src/server/MockDispatcherPlugins.js +22 -0
- package/src/server/Mockaton.test.config.js +17 -0
- package/src/server/Mockaton.test.js +109 -84
- package/src/server/Watcher.js +19 -2
- package/src/server/WatcherDevClient.js +1 -1
- package/src/server/cli.js +3 -0
- package/src/server/cli.test.js +38 -0
- package/src/server/config.js +2 -1
- package/src/server/utils/UrlParsers.js +1 -0
- package/src/server/utils/mime.js +3 -3
- package/src/client/indexHtml.js +0 -31
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export { Commander } from './src/client/ApiCommander.js'
|
|
2
|
+
export { API } from './src/client/ApiConstants.js'
|
|
2
3
|
|
|
3
4
|
export { Mockaton } from './src/server/Mockaton.js'
|
|
4
5
|
export { jwtCookie } from './src/server/utils/jwt.js'
|
|
5
|
-
export { jsToJsonPlugin } from './src/server/
|
|
6
|
+
export { jsToJsonPlugin, echoFilePlugin } from './src/server/MockDispatcherPlugins.js'
|
|
6
7
|
export { parseJSON, BodyReaderError } from './src/server/utils/HttpIncomingMessage.js'
|
|
7
8
|
export { parseSplats, parseQueryParams } from './src/server/utils/UrlParsers.js'
|
|
8
9
|
|
package/package.json
CHANGED
|
@@ -30,6 +30,9 @@ export class Commander {
|
|
|
30
30
|
/** @returns {Promise<Response>} */
|
|
31
31
|
setCorsAllowed = value => this.#patch(API.cors, value)
|
|
32
32
|
|
|
33
|
+
/** @returns {Promise<Response>} */
|
|
34
|
+
setWatchMocks = enabled => this.#patch(API.watchMocks, enabled)
|
|
35
|
+
|
|
33
36
|
/** @returns {Promise<Response>} */
|
|
34
37
|
setProxyFallback = proxyAddr => this.#patch(API.fallback, proxyAddr)
|
|
35
38
|
|
|
@@ -23,11 +23,14 @@ export const API = {
|
|
|
23
23
|
throws: MOUNT + '/throws',
|
|
24
24
|
toggle500: MOUNT + '/toggle500',
|
|
25
25
|
watchHotReload: MOUNT + '/watch-hot-reload',
|
|
26
|
+
watchMocks: MOUNT + '/watch-mocks',
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
export const HEADER_502 = 'Mockaton502'
|
|
29
30
|
export const HEADER_SYNC_VERSION = 'sync_version'
|
|
30
31
|
|
|
31
32
|
export const DEFAULT_MOCK_COMMENT = '(default)'
|
|
32
|
-
export const UNKNOWN_MIME_EXT = 'unknown'
|
|
33
33
|
export const LONG_POLL_SERVER_TIMEOUT = 8_000
|
|
34
|
+
|
|
35
|
+
export const EXT_UNKNOWN_MIME = 'unknown'
|
|
36
|
+
export const EXT_EMPTY = 'empty'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { API } from './ApiConstants.js'
|
|
2
|
+
|
|
3
|
+
export const CSP = [
|
|
4
|
+
`default-src 'self'`,
|
|
5
|
+
`img-src data: blob: 'self'`
|
|
6
|
+
].join(';')
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
// language=html
|
|
10
|
+
export const IndexHtml = (hotReloadEnabled, version) =>
|
|
11
|
+
`
|
|
12
|
+
<!DOCTYPE html>
|
|
13
|
+
<html lang="en-US">
|
|
14
|
+
<head>
|
|
15
|
+
<meta charset="UTF-8">
|
|
16
|
+
<base href="${API.dashboard}/">
|
|
17
|
+
|
|
18
|
+
<script type="module" src="app.js"></script>
|
|
19
|
+
<link rel="preload" href="${API.state}" as="fetch" crossorigin>
|
|
20
|
+
|
|
21
|
+
<link rel="icon" href="data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m235 33.7v202c0 9.19-5.81 14-17.4 14-11.6 0-17.4-4.83-17.4-14v-151c-0.115-4.49-6.72-5.88-8.46-0.87l-48.3 155c-2.22 7.01-7.72 10.1-16 9.9-3.63-0.191-7.01-1.14-9.66-2.89-2.89-1.72-4.83-4.34-5.57-7.72-11.1-37-22.6-74.3-34.1-111-4.34-14-8.95-31.4-14-48.3-1.82-4.83-8.16-5.32-8.46 1.16v156c0 9.19-5.81 14-17.4 14-11.6 0-17.4-4.83-17.4-14v-207c0-5.74 2.62-13.2 9.39-16.3 7.5-3.14 15-4.05 21.8-3.8 3.14 0 6.03 0.686 8.95 1.46 3.14 0.797 6.03 1.98 8.7 3.63 2.65 1.38 5.32 3.14 7.5 5.57 2.22 2.22 3.87 4.83 5.07 7.72l45.8 157c4.63-15.9 32.4-117 33.3-121 4.12-13.8 7.72-26.5 10.9-38.7 1.16-2.65 2.89-5.32 5.07-7.5 2.15-2.15 4.58-4.12 7.5-5.32 2.65-1.57 5.57-2.89 8.46-3.63 3.14-0.797 9.44-0.988 12.1-0.988 11.6 1.07 29.4 9.14 29.4 27z' fill='%23808080'/%3E%3C/svg%3E">
|
|
22
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
23
|
+
<meta name="description" content="HTTP Mock Server">
|
|
24
|
+
<title>Mockaton v${version}</title>
|
|
25
|
+
</head>
|
|
26
|
+
<body>
|
|
27
|
+
${hotReloadEnabled
|
|
28
|
+
? '<script type="module" src="watcherDev.js"></script>'
|
|
29
|
+
: ''}
|
|
30
|
+
</body>
|
|
31
|
+
</html>
|
|
32
|
+
`.trim()
|
package/src/client/app-store.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Commander } from './ApiCommander.js'
|
|
2
2
|
import { parseFilename, extractComments } from './Filename.js'
|
|
3
|
+
import { EXT_UNKNOWN_MIME, EXT_EMPTY } from './ApiConstants.js'
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
export const t = translation => translation[0]
|
|
@@ -20,23 +21,11 @@ export const store = {
|
|
|
20
21
|
|
|
21
22
|
collectProxied: false,
|
|
22
23
|
proxyFallback: '',
|
|
24
|
+
showProxyField: null,
|
|
23
25
|
get canProxy() {
|
|
24
26
|
return Boolean(store.proxyFallback)
|
|
25
27
|
},
|
|
26
28
|
|
|
27
|
-
getSyncVersion: api.getSyncVersion,
|
|
28
|
-
|
|
29
|
-
async fetchState() {
|
|
30
|
-
try {
|
|
31
|
-
const response = await api.getState()
|
|
32
|
-
if (!response.ok) throw response
|
|
33
|
-
Object.assign(store, await response.json())
|
|
34
|
-
store.render()
|
|
35
|
-
}
|
|
36
|
-
catch (error) { store.onError(error) }
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
|
|
40
29
|
groupByMethod: initPreference('groupByMethod'),
|
|
41
30
|
toggleGroupByMethod() {
|
|
42
31
|
store.groupByMethod = !store.groupByMethod
|
|
@@ -44,7 +33,6 @@ export const store = {
|
|
|
44
33
|
store.render()
|
|
45
34
|
},
|
|
46
35
|
|
|
47
|
-
|
|
48
36
|
chosenLink: { method: '', urlMask: '' },
|
|
49
37
|
setChosenLink(method, urlMask) {
|
|
50
38
|
store.chosenLink = { method, urlMask }
|
|
@@ -54,70 +42,71 @@ export const store = {
|
|
|
54
42
|
},
|
|
55
43
|
|
|
56
44
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
45
|
+
getSyncVersion: api.getSyncVersion,
|
|
46
|
+
|
|
47
|
+
_request(action, onSuccess) {
|
|
48
|
+
Promise.try(async () => {
|
|
49
|
+
const response = await action()
|
|
50
|
+
if (response.ok) return response
|
|
51
|
+
throw response
|
|
52
|
+
})
|
|
53
|
+
.then(onSuccess)
|
|
54
|
+
.catch(store.onError)
|
|
65
55
|
},
|
|
66
56
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
57
|
+
fetchState() {
|
|
58
|
+
store._request(api.getState, async response => {
|
|
59
|
+
Object.assign(store, await response.json())
|
|
60
|
+
|
|
61
|
+
if (store.showProxyField === null) // isFirstCall
|
|
62
|
+
store.showProxyField = Boolean(store.proxyFallback)
|
|
63
|
+
|
|
64
|
+
store.render()
|
|
65
|
+
})
|
|
74
66
|
},
|
|
75
67
|
|
|
68
|
+
reset() {
|
|
69
|
+
store._request(api.reset, () => {
|
|
70
|
+
store.setChosenLink('', '')
|
|
71
|
+
store.fetchState()
|
|
72
|
+
})
|
|
73
|
+
},
|
|
76
74
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
bulkSelectByComment(value) {
|
|
76
|
+
store._request(() => api.bulkSelectByComment(value), () => {
|
|
77
|
+
store.fetchState()
|
|
78
|
+
})
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
setGlobalDelay(value) {
|
|
82
|
+
store._request(() => api.setGlobalDelay(value), () => {
|
|
81
83
|
store.delay = value
|
|
82
|
-
}
|
|
83
|
-
catch (error) { store.onError(error) }
|
|
84
|
+
})
|
|
84
85
|
},
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const response = await api.setGlobalDelayJitter(value)
|
|
89
|
-
if (!response.ok) throw response
|
|
87
|
+
setGlobalDelayJitter(value) {
|
|
88
|
+
store._request(() => api.setGlobalDelayJitter(value), () => {
|
|
90
89
|
store.delayJitter = value
|
|
91
|
-
}
|
|
92
|
-
catch (error) { store.onError(error) }
|
|
90
|
+
})
|
|
93
91
|
},
|
|
94
92
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const response = await api.selectCookie(name)
|
|
98
|
-
if (!response.ok) throw response
|
|
93
|
+
selectCookie(name) {
|
|
94
|
+
store._request(() => api.selectCookie(name), async response => {
|
|
99
95
|
store.cookies = await response.json()
|
|
100
|
-
}
|
|
101
|
-
catch (error) { store.onError(error) }
|
|
96
|
+
})
|
|
102
97
|
},
|
|
103
98
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const response = await api.setProxyFallback(value)
|
|
107
|
-
if (!response.ok) throw response
|
|
99
|
+
setProxyFallback(value) {
|
|
100
|
+
store._request(() => api.setProxyFallback(value), () => {
|
|
108
101
|
store.proxyFallback = value
|
|
109
102
|
store.render()
|
|
110
|
-
}
|
|
111
|
-
catch (error) { store.onError(error) }
|
|
103
|
+
})
|
|
112
104
|
},
|
|
113
105
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const response = await api.setCollectProxied(checked)
|
|
117
|
-
if (!response.ok) throw response
|
|
106
|
+
setCollectProxied(checked) {
|
|
107
|
+
store._request(() => api.setCollectProxied(checked), () => {
|
|
118
108
|
store.collectProxied = checked
|
|
119
|
-
}
|
|
120
|
-
catch (error) { store.onError(error) }
|
|
109
|
+
})
|
|
121
110
|
},
|
|
122
111
|
|
|
123
112
|
|
|
@@ -179,66 +168,47 @@ export const store = {
|
|
|
179
168
|
store.renderRow(method, urlMask)
|
|
180
169
|
},
|
|
181
170
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const response = await api.select(file)
|
|
185
|
-
if (!response.ok) throw response
|
|
171
|
+
selectFile(file) {
|
|
172
|
+
store._request(() => api.select(file), async response => {
|
|
186
173
|
const { method, urlMask } = parseFilename(file)
|
|
187
174
|
store.setBroker(await response.json())
|
|
188
175
|
store.setChosenLink(method, urlMask)
|
|
189
176
|
store.renderRow(method, urlMask)
|
|
190
|
-
}
|
|
191
|
-
catch (error) { store.onError(error) }
|
|
177
|
+
})
|
|
192
178
|
},
|
|
193
179
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const response = await api.toggle500(method, urlMask)
|
|
197
|
-
if (!response.ok) throw response
|
|
180
|
+
toggle500(method, urlMask) {
|
|
181
|
+
store._request(() => api.toggle500(method, urlMask), async response => {
|
|
198
182
|
store.setBroker(await response.json())
|
|
199
183
|
store.setChosenLink(method, urlMask)
|
|
200
184
|
store.renderRow(method, urlMask)
|
|
201
|
-
}
|
|
202
|
-
catch (error) { store.onError(error) }
|
|
185
|
+
})
|
|
203
186
|
},
|
|
204
187
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const response = await api.setRouteIsProxied(method, urlMask, checked)
|
|
208
|
-
if (!response.ok) throw response
|
|
188
|
+
setProxied(method, urlMask, checked) {
|
|
189
|
+
store._request(() => api.setRouteIsProxied(method, urlMask, checked), async response => {
|
|
209
190
|
store.setBroker(await response.json())
|
|
210
191
|
store.setChosenLink(method, urlMask)
|
|
211
192
|
store.renderRow(method, urlMask)
|
|
212
|
-
}
|
|
213
|
-
catch (error) { store.onError(error) }
|
|
193
|
+
})
|
|
214
194
|
},
|
|
215
195
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const response = await api.setRouteIsDelayed(method, urlMask, checked)
|
|
219
|
-
if (!response.ok) throw response
|
|
196
|
+
setDelayed(method, urlMask, checked) {
|
|
197
|
+
store._request(() => api.setRouteIsDelayed(method, urlMask, checked), async response => {
|
|
220
198
|
store.setBroker(await response.json())
|
|
221
|
-
}
|
|
222
|
-
catch (error) { store.onError(error) }
|
|
199
|
+
})
|
|
223
200
|
},
|
|
224
201
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
try {
|
|
228
|
-
const response = await api.setStaticRouteIsDelayed(route, checked)
|
|
229
|
-
if (!response.ok) throw response
|
|
202
|
+
setDelayedStatic(route, checked) {
|
|
203
|
+
store._request(() => api.setStaticRouteIsDelayed(route, checked), () => {
|
|
230
204
|
store.staticBrokers[route].delayed = checked
|
|
231
|
-
}
|
|
232
|
-
catch (error) { store.onError(error) }
|
|
205
|
+
})
|
|
233
206
|
},
|
|
234
207
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
const response = await api.setStaticRouteStatus(route, status)
|
|
238
|
-
if (!response.ok) throw response
|
|
208
|
+
setStaticRouteStatus(route, status) {
|
|
209
|
+
store._request(() => api.setStaticRouteStatus(route, status), () => {
|
|
239
210
|
store.staticBrokers[route].status = status
|
|
240
|
-
}
|
|
241
|
-
catch (error) { store.onError(error) }
|
|
211
|
+
})
|
|
242
212
|
}
|
|
243
213
|
}
|
|
244
214
|
|
|
@@ -286,20 +256,18 @@ export function dittoSplitPaths(paths) {
|
|
|
286
256
|
const pathsInParts = paths.map(p => p.split('/').filter(Boolean))
|
|
287
257
|
|
|
288
258
|
for (let i = 1; i < paths.length; i++) {
|
|
289
|
-
const
|
|
290
|
-
const
|
|
259
|
+
const prev = pathsInParts[i - 1]
|
|
260
|
+
const curr = pathsInParts[i]
|
|
291
261
|
|
|
262
|
+
const min = Math.min(curr.length, prev.length)
|
|
292
263
|
let j = 0
|
|
293
|
-
while (
|
|
294
|
-
j < currParts.length &&
|
|
295
|
-
j < prevParts.length &&
|
|
296
|
-
currParts[j] === prevParts[j])
|
|
264
|
+
while (j < min && curr[j] === prev[j])
|
|
297
265
|
j++
|
|
298
266
|
|
|
299
267
|
if (!j) // no common dirs
|
|
300
268
|
result.push(['', paths[i]])
|
|
301
269
|
else {
|
|
302
|
-
const ditto = '/' +
|
|
270
|
+
const ditto = '/' + curr.slice(0, j).join('/') + '/'
|
|
303
271
|
result.push([ditto, paths[i].slice(ditto.length)])
|
|
304
272
|
}
|
|
305
273
|
}
|
|
@@ -377,7 +345,7 @@ export class BrokerRowModel {
|
|
|
377
345
|
const { status, ext } = parseFilename(file)
|
|
378
346
|
return [
|
|
379
347
|
status,
|
|
380
|
-
ext ===
|
|
348
|
+
ext === EXT_EMPTY || ext === EXT_UNKNOWN_MIME ? '' : ext,
|
|
381
349
|
extractComments(file).join(' ')
|
|
382
350
|
].filter(Boolean).join(' ')
|
|
383
351
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
:root {
|
|
2
2
|
color-scheme: light dark;
|
|
3
3
|
--colorBackground: light-dark(#fff, #181818);
|
|
4
|
-
--
|
|
4
|
+
--colorInputBackground: light-dark(#fff, #222);
|
|
5
5
|
--colorSecondaryButtonBackground: light-dark(#fcfcfc, #2c2c2c);
|
|
6
6
|
--colorHeaderBackground: light-dark(#f2f2f3, #141414);
|
|
7
7
|
--colorComboBoxBackground: light-dark(#eee, #2a2a2a);
|
|
8
|
-
--colorBorder: light-dark(#e0e0e0, #
|
|
8
|
+
--colorBorder: light-dark(#e0e0e0, #323232);
|
|
9
|
+
--colorBorderActive: light-dark(#c8c8c8, #3c3c3c);
|
|
9
10
|
--colorSecondaryAction: light-dark(#666, #aaa);
|
|
10
11
|
--colorLabel: light-dark(#555, #aaa);
|
|
11
12
|
--colorDisabledMockSelector: light-dark(#444, #a9b9b9);
|
|
@@ -17,7 +18,7 @@
|
|
|
17
18
|
--colorPurple: light-dark(#9b71e8, #ae81ff);
|
|
18
19
|
--colorGreen: light-dark(#388e3c, #a6e22e);
|
|
19
20
|
--color4xxBackground: light-dark(#ffedd1, #68554a);
|
|
20
|
-
|
|
21
|
+
|
|
21
22
|
accent-color: var(--colorAccent);
|
|
22
23
|
--radius: 16px;
|
|
23
24
|
}
|
|
@@ -115,10 +116,6 @@ header {
|
|
|
115
116
|
opacity: 1;
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
@media (max-width: 740px) {
|
|
119
|
-
display: none;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
119
|
svg {
|
|
123
120
|
width: 120px;
|
|
124
121
|
pointer-events: none;
|
|
@@ -126,6 +123,20 @@ header {
|
|
|
126
123
|
}
|
|
127
124
|
}
|
|
128
125
|
|
|
126
|
+
@media (max-width: 570px) {
|
|
127
|
+
.Logo {
|
|
128
|
+
display: none;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
&:has(.FallbackBackend) {
|
|
133
|
+
@media (max-width: 740px) {
|
|
134
|
+
.Logo {
|
|
135
|
+
display: none;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
129
140
|
> div {
|
|
130
141
|
display: flex;
|
|
131
142
|
width: 100%;
|
|
@@ -133,9 +144,11 @@ header {
|
|
|
133
144
|
align-items: flex-end;
|
|
134
145
|
gap: 16px 12px;
|
|
135
146
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
147
|
+
&:has(.FallbackBackend) {
|
|
148
|
+
@media (max-width: 600px) {
|
|
149
|
+
.HelpLink {
|
|
150
|
+
margin-left: unset;
|
|
151
|
+
}
|
|
139
152
|
}
|
|
140
153
|
}
|
|
141
154
|
}
|
|
@@ -209,7 +222,7 @@ header {
|
|
|
209
222
|
margin-top: 2px;
|
|
210
223
|
color: var(--colorText);
|
|
211
224
|
font-size: 11px;
|
|
212
|
-
background-color: var(--
|
|
225
|
+
background-color: var(--colorInputBackground);
|
|
213
226
|
border-radius: var(--radius);
|
|
214
227
|
}
|
|
215
228
|
|
|
@@ -301,14 +314,14 @@ main {
|
|
|
301
314
|
}
|
|
302
315
|
|
|
303
316
|
.leftSide {
|
|
304
|
-
width: 100% !important;
|
|
317
|
+
width: 100% !important; /* because it's resizable in js */
|
|
305
318
|
height: 50%;
|
|
306
319
|
border-right: 0;
|
|
307
320
|
}
|
|
308
321
|
}
|
|
309
322
|
|
|
310
323
|
.leftSide {
|
|
311
|
-
width: 50%;
|
|
324
|
+
width: 50%;
|
|
312
325
|
border-top: 1px solid var(--colorBorder);
|
|
313
326
|
border-right: 1px solid var(--colorBorder);
|
|
314
327
|
}
|
|
@@ -323,14 +336,31 @@ main {
|
|
|
323
336
|
.Resizer {
|
|
324
337
|
position: absolute;
|
|
325
338
|
top: 0;
|
|
326
|
-
left:
|
|
339
|
+
left: -1px;
|
|
327
340
|
width: 8px;
|
|
328
341
|
height: 100%;
|
|
329
|
-
border-left:
|
|
342
|
+
border-left: 1px solid transparent;
|
|
330
343
|
cursor: col-resize;
|
|
331
344
|
|
|
345
|
+
&:hover,
|
|
332
346
|
&:active {
|
|
333
|
-
border-color: var(--
|
|
347
|
+
border-color: var(--colorBorderActive);
|
|
348
|
+
}
|
|
349
|
+
&::before,
|
|
350
|
+
&::after {
|
|
351
|
+
position: absolute;
|
|
352
|
+
left: -2px;
|
|
353
|
+
content: '';
|
|
354
|
+
}
|
|
355
|
+
&::before {
|
|
356
|
+
top: calc(50% + 6px);
|
|
357
|
+
height: 22px;
|
|
358
|
+
border-left: 3px solid var(--colorBackground);
|
|
359
|
+
}
|
|
360
|
+
&::after {
|
|
361
|
+
top: calc(50% + 10px);
|
|
362
|
+
height: 14px;
|
|
363
|
+
border-left: 3px dotted var(--colorBorder);
|
|
334
364
|
}
|
|
335
365
|
}
|
|
336
366
|
}
|
|
@@ -364,7 +394,7 @@ main {
|
|
|
364
394
|
text-align-last: center;
|
|
365
395
|
color: var(--colorText);
|
|
366
396
|
font-size: 11px;
|
|
367
|
-
background-color: var(--
|
|
397
|
+
background-color: var(--colorInputBackground);
|
|
368
398
|
border-radius: var(--radius);
|
|
369
399
|
}
|
|
370
400
|
}
|
|
@@ -622,7 +652,7 @@ main {
|
|
|
622
652
|
left: -16px;
|
|
623
653
|
width: calc(100% + 32px);
|
|
624
654
|
height: 2px;
|
|
625
|
-
background: var(--
|
|
655
|
+
background: var(--colorInputBackground);
|
|
626
656
|
|
|
627
657
|
> div {
|
|
628
658
|
position: absolute;
|
|
@@ -651,6 +681,7 @@ main {
|
|
|
651
681
|
bottom: 12px;
|
|
652
682
|
left: 12px;
|
|
653
683
|
padding: 12px 16px;
|
|
684
|
+
padding-right: 42px;
|
|
654
685
|
cursor: pointer;
|
|
655
686
|
background: var(--colorRed);
|
|
656
687
|
color: white;
|
|
@@ -659,18 +690,16 @@ main {
|
|
|
659
690
|
transform: translateY(20px);
|
|
660
691
|
animation: _kfToastIn 240ms forwards;
|
|
661
692
|
|
|
662
|
-
|
|
693
|
+
&::after {
|
|
663
694
|
position: absolute;
|
|
664
695
|
top: 0;
|
|
665
|
-
|
|
666
|
-
width:
|
|
667
|
-
height:
|
|
696
|
+
right: 16px;
|
|
697
|
+
width: 12px;
|
|
698
|
+
height: 12px;
|
|
668
699
|
text-align: center;
|
|
669
700
|
content: '×';
|
|
670
701
|
font-size: 28px;
|
|
671
702
|
line-height: 34px;
|
|
672
|
-
border-radius: var(--radius);
|
|
673
|
-
background: rgba(0, 0, 0, 0.5);
|
|
674
703
|
}
|
|
675
704
|
}
|
|
676
705
|
@keyframes _kfToastIn {
|