75 lines
2.0 KiB
Plaintext
75 lines
2.0 KiB
Plaintext
import { SPACE, COMMA, LENGTH, NUMBER, ANGLE } from '../tokenTypes'
|
|
|
|
const oneOfType = tokenType => functionStream => {
|
|
const value = functionStream.expect(tokenType)
|
|
functionStream.expectEmpty()
|
|
return value
|
|
}
|
|
|
|
const singleNumber = oneOfType(NUMBER)
|
|
const singleLength = oneOfType(LENGTH)
|
|
const singleAngle = oneOfType(ANGLE)
|
|
const xyTransformFactory = tokenType => (
|
|
key,
|
|
valueIfOmitted
|
|
) => functionStream => {
|
|
const x = functionStream.expect(tokenType)
|
|
|
|
let y
|
|
if (functionStream.hasTokens()) {
|
|
functionStream.expect(COMMA)
|
|
y = functionStream.expect(tokenType)
|
|
} else if (valueIfOmitted !== undefined) {
|
|
y = valueIfOmitted
|
|
} else {
|
|
// Assumption, if x === y, then we can omit XY
|
|
// I.e. scale(5) => [{ scale: 5 }] rather than [{ scaleX: 5 }, { scaleY: 5 }]
|
|
return x
|
|
}
|
|
|
|
functionStream.expectEmpty()
|
|
|
|
return [{ [`${key}Y`]: y }, { [`${key}X`]: x }]
|
|
}
|
|
const xyNumber = xyTransformFactory(NUMBER)
|
|
const xyLength = xyTransformFactory(LENGTH)
|
|
const xyAngle = xyTransformFactory(ANGLE)
|
|
|
|
const partTransforms = {
|
|
perspective: singleNumber,
|
|
scale: xyNumber('scale'),
|
|
scaleX: singleNumber,
|
|
scaleY: singleNumber,
|
|
translate: xyLength('translate', 0),
|
|
translateX: singleLength,
|
|
translateY: singleLength,
|
|
rotate: singleAngle,
|
|
rotateX: singleAngle,
|
|
rotateY: singleAngle,
|
|
rotateZ: singleAngle,
|
|
skewX: singleAngle,
|
|
skewY: singleAngle,
|
|
skew: xyAngle('skew', '0deg'),
|
|
}
|
|
|
|
export default tokenStream => {
|
|
let transforms = []
|
|
|
|
let didParseFirst = false
|
|
while (tokenStream.hasTokens()) {
|
|
if (didParseFirst) tokenStream.expect(SPACE)
|
|
|
|
const functionStream = tokenStream.expectFunction()
|
|
const { functionName } = functionStream
|
|
let transformedValues = partTransforms[functionName](functionStream)
|
|
if (!Array.isArray(transformedValues)) {
|
|
transformedValues = [{ [functionName]: transformedValues }]
|
|
}
|
|
transforms = transformedValues.concat(transforms)
|
|
|
|
didParseFirst = true
|
|
}
|
|
|
|
return { transform: transforms }
|
|
}
|