siphon-cli
Version:
Simple bundler for web applications. 📦🔧🧡
392 lines (391 loc) • 16.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var errors_1 = require("../../errors");
var utils_1 = require("../../../utils");
var types_1 = require("../../../types");
function parse(src) {
function parserCore(text, root) {
if (root === void 0) { root = new types_1.Stylesheet(0, 0); }
function readString(i) {
var marker = text[i++], str = "";
while (text[i] && text[i] !== marker) {
if (text[i] === "\n") {
errors_1.default.enc("CSS_STRING_OR_URI_EXPECTED", src, i);
}
else if (text[i] === "\\" &&
text[i + 1] === marker &&
text[i - 1] !== "\\") {
str += text[(i += 2)] + marker;
}
else
str += text[i++];
}
return { str: str, end: i + 1, marker: marker };
}
function readAtRule(i) {
function readImportRule(start, i) {
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
var href = "", resourcetype;
switch (true) {
case text.slice(i, i + 4) === "url(":
i += 4;
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
if (!/'|"/.test(text[i])) {
while (text[i] && text[i] !== ")") {
if (text[i] === "\n") {
errors_1.default.enc("CLOSING_BRAC_EXPECTED", src, i);
}
else
href += text[i++];
}
(0, utils_1.checkForEnd)(text[i], src);
i++;
break;
}
case /'|"/.test(text[i]):
var movethrough = readString(i);
href = movethrough.str;
i = movethrough.end;
break;
default:
errors_1.default.enc("CSS_STRING_OR_URI_EXPECTED", src, i);
}
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
if (text[i] !== ";" && i !== text.length)
errors_1.default.enc("SEMI_COLON_EXPECTED", src, i);
href = href.trim().trimEnd();
if (href.startsWith("http://") || href.startsWith("https://")) {
resourcetype = "cross-site";
}
else
resourcetype = "local";
var rule = new types_1.ImportRule(start, i, resourcetype);
rule.href = href;
root.rules.push(rule);
read(i + 1);
}
function readFontFaceRule(start, i) {
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
if (text[i] !== "{")
errors_1.default.enc("CSS_OPEN_CURL_EXPECTED", src, i);
i++;
var rule = new types_1.FontFaceRule(start, 0);
function readFontStyles() {
var property = "";
var value = "";
while (text[i] && text[i] !== ":")
property += text[i++];
if (!text[i])
errors_1.default.enc("COLON_EXPECTED", src, i);
i++;
while (text[i] && !/;|}/.test(text[i])) {
if (/'|"/.test(text[i])) {
var strn = readString(i);
value += strn.marker + strn.str + strn.marker;
i = strn.end;
}
else
value += text[i++];
}
switch (property.trim().trimEnd()) {
case "font-family":
rule.family = value.trim().trimEnd();
break;
case "src":
rule.source = value.trim().trimEnd();
break;
default:
break;
}
while (text[i] === ";" || (0, utils_1.isSpaceCharac)(text[i]))
i++;
if (text[i] !== "}")
readFontStyles();
}
readFontStyles();
rule.loc.end = i;
root.rules.push(rule);
read(i + 1);
}
function readMediaRule(start, i) {
var params = "";
while (text[i] && text[i] !== "{") {
if (/"|'/.test(text[i])) {
var value = readString(i);
params += value.marker + value.str + value.marker;
i = value.end;
}
else
params += text[i++];
}
i++;
var level = 1, chunk = "";
while (text[i] && level) {
if (text[i] === "{")
level++;
else if (text[i] === "}")
level--;
chunk += text[i++];
}
chunk = chunk.slice(0, -1);
var mediarule = parserCore(chunk, new types_1.MediaRule(start, 0, params.trim().trimEnd()));
mediarule.loc.end = i;
root.rules.push(mediarule);
read(i);
}
function readSupportRule(start, i) {
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
var inverseQuery = false;
if (text.slice(i, i + 3) === "not") {
inverseQuery = true;
i += 3;
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
}
if (!text[i] || text[i] !== "(")
errors_1.default.enc("OPEN_BRAC_EXPECTED", src, i);
i++;
var query = "";
while (text[i] && text[i] !== ")") {
if (/'|"/.test(text[i])) {
var str = readString(i);
query += str.marker + str.str + str.marker;
i = str.end;
}
else
query += text[i++];
}
if (!text[i])
errors_1.default.enc("CLOSING_BRAC_EXPECTED", src, i);
i++;
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
if (text[i] !== "{")
errors_1.default.enc("CSS_OPEN_CURL_EXPECTED", src, i);
i++;
var level = 1, chunk = "";
while (text[i] && level) {
if (text[i] === "{")
level++;
else if (text[i] === "}")
level--;
chunk += text[i++];
}
var supportRule = parserCore(chunk.slice(0, -1).trim().trimEnd(), new types_1.SupportRule(start, i, query, inverseQuery));
supportRule.loc.end = i;
root.rules.push(supportRule);
read(i);
}
function readKeyframeRule(start, i) {
var keyframeRule = new types_1.KeyframeRule(start, 0);
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
var identifier = "";
while (text[i] && text[i] !== "{")
identifier += text[i++];
if (!text[i])
errors_1.default.enc("CSS_OPEN_CURL_EXPECTED", src, i);
i++;
if ((0, utils_1.isIllegalCSSIdentifier)(identifier))
errors_1.default.enc("CSS_INVALID_IDENTIFIER", src, i);
keyframeRule.identifier = identifier.trimEnd();
function readFrameStyles(frame, i) {
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
var style = new types_1.Style("", "");
style.loc.start = i;
while (text[i] && text[i] !== ":")
style.property += text[i++];
style.property = style.property.trimEnd();
i++;
while (text[i] && !/\;|}/.test(text[i])) {
if (/'|"/.test(text[i])) {
var movethr = readString(i);
style.value += movethr.marker + movethr.str + movethr.marker;
i = movethr.end;
}
else
style.value += text[i++];
}
style.value = style.value.trim().trimEnd();
if (!text[i])
errors_1.default.enc("CSS_OPEN_CURL_EXPECTED", src, i);
style.loc.end = i;
frame.styles.push(style);
frame.notation[style.property] = style.value;
while (text[i] === ";" || (0, utils_1.isSpaceCharac)(text[i]))
i++;
if (text[i] !== "}")
return readFrameStyles(frame, i);
else
return i + 1;
}
function readFrame() {
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
var frame = { mark: "", styles: [], notation: {} };
while (text[i] && text[i] !== "{")
frame.mark += text[i++];
if (!text[i])
errors_1.default.enc("CSS_OPEN_CURL_EXPECTED", src, i);
frame.mark = frame.mark.trimEnd();
i = readFrameStyles(frame, ++i);
keyframeRule.frames.push(frame);
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
if (text[i] !== "}")
readFrame();
}
readFrame();
keyframeRule.loc.end = i;
root.rules.push(keyframeRule);
read(i + 1);
}
function readCharsetRule(start, i) {
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
}
var atRuleName = "";
var start = i - 1;
while (text[i] && /[a-zA-Z]|-|[0-9]/.test(text[i])) {
atRuleName += text[i++];
}
switch (atRuleName) {
case "import":
readImportRule(start, i);
break;
case "font-face":
readFontFaceRule(start, i);
break;
case "media":
readMediaRule(start, i);
break;
case "supports":
readSupportRule(start, i);
break;
case "keyframes":
readKeyframeRule(start, i);
break;
case "charset":
readCharsetRule(start, i);
break;
default:
break;
}
}
function readStyleRule(i) {
var start = i;
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
var selectorsRaw = "";
while (text[i] && text[i] !== "{") {
if (/'|"/.test(text[i])) {
var movethr = readString(i);
selectorsRaw += movethr.marker + movethr.str + movethr.marker;
i = movethr.end;
}
else
selectorsRaw += text[i++];
}
if (!text[i])
errors_1.default.enc("CSS_OPEN_CURL_EXPECTED", src, i);
i++;
var rule = new types_1.StyleRule();
rule.loc.start = start;
var selector = "";
for (var x = 0; selectorsRaw[x]; x++) {
if (/'|"/.test(selectorsRaw[x])) {
var marker = selectorsRaw[x++];
selector += marker;
while (selectorsRaw[x] && selectorsRaw[x] !== marker) {
if (selectorsRaw[x] === "\n") {
errors_1.default.enc("CSS_STRING_OR_URI_EXPECTED", src, i);
}
else if (selectorsRaw[x] === "\\" &&
selectorsRaw[x + 1] === marker &&
selectorsRaw[x - 1] !== "\\") {
selector += selectorsRaw[(x += 2)] + marker;
}
else
selector += selectorsRaw[x++];
}
selector += marker;
}
else if (selectorsRaw[x] === ",") {
rule.selectors.push(selector.trim().trimEnd());
selector = "";
}
else
selector += selectorsRaw[x];
}
rule.selectors.push(selector.trim().trimEnd());
function readStyles() {
var start = i;
var property = "", value = "";
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
if (text[i] === "}")
return;
while (text[i] && text[i] !== ":")
property += text[i++];
i++;
while (text[i] && text[i] !== ";" && text[i] !== "}") {
if (/'|"/.test(text[i])) {
var strn = readString(i);
value += strn.marker + strn.str + strn.marker;
i = strn.end;
}
else
value += text[i++];
}
var relation = new types_1.Style(property.trim().trimEnd(), value.trim().trimEnd());
relation.loc.start = start;
relation.loc.end = i;
rule.content.push(relation);
rule.notation[relation.property] = relation.value;
while (text[i] === ";" || (0, utils_1.isSpaceCharac)(text[i]))
i++;
if (text[i] !== "}")
readStyles();
}
readStyles();
rule.loc.end = i;
root.rules.push(rule);
read(i + 1);
}
function removeComments() {
var stripped = "";
for (var i = 0; text[i]; i++) {
if (text.slice(i, i + 2) === "/*") {
i += 2;
while (text[i] && text.slice(i, i + 2) !== "*/")
i++;
i++;
}
else
stripped += text[i];
}
return stripped.trim().trimEnd();
}
text = removeComments();
function read(i) {
while ((0, utils_1.isSpaceCharac)(text[i]))
i++;
if (text[i])
if (text[i] === "@")
readAtRule(i + 1);
else if (/[a-z]|[A-Z]|:|#|.|\[/.test(text[i]))
readStyleRule(i);
}
read(0);
root.loc.end = text.length;
return root;
}
return parserCore(src.toString());
}
exports.default = parse;