@chasemoskal/magical
Version:
web toolkit for lit apps
76 lines • 3.07 kB
JavaScript
import { Token } from "./types.js";
import { CamelCssMissingClosingBraceError, setupTracedErrors } from "../../errors.js";
export function* parse(tokens) {
let frame;
const stack = [];
for (const token of tokens) {
const error = setupTracedErrors(token.trace);
switch (token.type) {
case Token.Type.Open:
case Token.Type.AtRule:
{
frame = {
selector: (token.type === Token.Type.AtRule)
? token.directive
: token.selector.replaceAll(/\s+/gm, " "),
ruleName: undefined,
rules: {},
childFrames: [],
};
stack.push(frame);
}
break;
case Token.Type.RuleName:
{
if (!frame)
throw error.ruleNamePlacement(token.name);
frame.ruleName = token.name;
}
break;
case Token.Type.RuleValue:
{
if (!frame || !frame.ruleName)
throw error.ruleValuePlacement(token.value);
frame.rules[frame.ruleName] = token.value;
frame.ruleName = undefined;
}
break;
case Token.Type.Close:
{
const completedFrame = stack.pop();
const parentFrame = stack.length > 0
? stack[stack.length - 1]
: undefined;
frame = parentFrame;
if (!completedFrame)
throw error.excessClosingBrace();
if (!completedFrame.selector)
throw error.missingSelectorOrAtRule();
if (parentFrame)
parentFrame.childFrames.push(completedFrame);
else {
function recursiveFrameToExpression(frame) {
if (frame.selector.startsWith("@")) {
return [
frame.selector,
frame.childFrames.map(recursiveFrameToExpression),
];
}
else {
return [
frame.selector,
frame.rules,
frame.childFrames.map(recursiveFrameToExpression),
];
}
}
yield recursiveFrameToExpression(completedFrame);
}
}
break;
}
}
if (stack.length > 0)
throw new CamelCssMissingClosingBraceError(stack.length);
}
//# sourceMappingURL=parse.js.map