100 lines
2.3 KiB
Plaintext
100 lines
2.3 KiB
Plaintext
import {
|
|
LENGTH,
|
|
UNSUPPORTED_LENGTH_UNIT,
|
|
PERCENT,
|
|
COLOR,
|
|
SPACE,
|
|
NONE,
|
|
} from '../tokenTypes'
|
|
|
|
export const directionFactory = ({
|
|
types = [LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT],
|
|
directions = ['Top', 'Right', 'Bottom', 'Left'],
|
|
prefix = '',
|
|
suffix = '',
|
|
}) => tokenStream => {
|
|
const values = []
|
|
|
|
// borderWidth doesn't currently allow a percent value, but may do in the future
|
|
values.push(tokenStream.expect(...types))
|
|
|
|
while (values.length < 4 && tokenStream.hasTokens()) {
|
|
tokenStream.expect(SPACE)
|
|
values.push(tokenStream.expect(...types))
|
|
}
|
|
|
|
tokenStream.expectEmpty()
|
|
|
|
const [top, right = top, bottom = top, left = right] = values
|
|
|
|
const keyFor = n => `${prefix}${directions[n]}${suffix}`
|
|
|
|
return {
|
|
[keyFor(0)]: top,
|
|
[keyFor(1)]: right,
|
|
[keyFor(2)]: bottom,
|
|
[keyFor(3)]: left,
|
|
}
|
|
}
|
|
|
|
export const parseShadowOffset = tokenStream => {
|
|
const width = tokenStream.expect(LENGTH)
|
|
const height = tokenStream.matches(SPACE) ? tokenStream.expect(LENGTH) : width
|
|
tokenStream.expectEmpty()
|
|
return { width, height }
|
|
}
|
|
|
|
export const parseShadow = tokenStream => {
|
|
let offsetX
|
|
let offsetY
|
|
let radius
|
|
let color
|
|
|
|
if (tokenStream.matches(NONE)) {
|
|
tokenStream.expectEmpty()
|
|
return {
|
|
offset: { width: 0, height: 0 },
|
|
radius: 0,
|
|
color: 'black',
|
|
}
|
|
}
|
|
|
|
let didParseFirst = false
|
|
while (tokenStream.hasTokens()) {
|
|
if (didParseFirst) tokenStream.expect(SPACE)
|
|
|
|
if (
|
|
offsetX === undefined &&
|
|
tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT)
|
|
) {
|
|
offsetX = tokenStream.lastValue
|
|
tokenStream.expect(SPACE)
|
|
offsetY = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT)
|
|
|
|
tokenStream.saveRewindPoint()
|
|
if (
|
|
tokenStream.matches(SPACE) &&
|
|
tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT)
|
|
) {
|
|
radius = tokenStream.lastValue
|
|
} else {
|
|
tokenStream.rewind()
|
|
}
|
|
} else if (color === undefined && tokenStream.matches(COLOR)) {
|
|
color = tokenStream.lastValue
|
|
} else {
|
|
tokenStream.throw()
|
|
}
|
|
|
|
didParseFirst = true
|
|
}
|
|
|
|
if (offsetX === undefined) tokenStream.throw()
|
|
|
|
return {
|
|
offset: { width: offsetX, height: offsetY },
|
|
radius: radius !== undefined ? radius : 0,
|
|
color: color !== undefined ? color : 'black',
|
|
}
|
|
}
|