UNPKG

siphon-cli

Version:

Simple bundler for web applications. 📦🔧🧡

392 lines (391 loc) • 16.7 kB
"use strict"; 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;