File size: 1,855 Bytes
bc20498
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { splitAtTopLevelOnly } from './splitAtTopLevelOnly'

let KEYWORDS = new Set(['inset', 'inherit', 'initial', 'revert', 'unset'])
let SPACE = /\ +(?![^(]*\))/g // Similar to the one above, but with spaces instead.
let LENGTH = /^-?(\d+|\.\d+)(.*?)$/g

export function parseBoxShadowValue(input) {
  let shadows = splitAtTopLevelOnly(input, ',')
  return shadows.map((shadow) => {
    let value = shadow.trim()
    let result = { raw: value }
    let parts = value.split(SPACE)
    let seen = new Set()

    for (let part of parts) {
      // Reset index, since the regex is stateful.
      LENGTH.lastIndex = 0

      // Keyword
      if (!seen.has('KEYWORD') && KEYWORDS.has(part)) {
        result.keyword = part
        seen.add('KEYWORD')
      }

      // Length value
      else if (LENGTH.test(part)) {
        if (!seen.has('X')) {
          result.x = part
          seen.add('X')
        } else if (!seen.has('Y')) {
          result.y = part
          seen.add('Y')
        } else if (!seen.has('BLUR')) {
          result.blur = part
          seen.add('BLUR')
        } else if (!seen.has('SPREAD')) {
          result.spread = part
          seen.add('SPREAD')
        }
      }

      // Color or unknown
      else {
        if (!result.color) {
          result.color = part
        } else {
          if (!result.unknown) result.unknown = []
          result.unknown.push(part)
        }
      }
    }

    // Check if valid
    result.valid = result.x !== undefined && result.y !== undefined

    return result
  })
}

export function formatBoxShadowValue(shadows) {
  return shadows
    .map((shadow) => {
      if (!shadow.valid) {
        return shadow.raw
      }

      return [shadow.keyword, shadow.x, shadow.y, shadow.blur, shadow.spread, shadow.color]
        .filter(Boolean)
        .join(' ')
    })
    .join(', ')
}