UNPKG

4.32 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.parseCss = parseCss;
7exports.cleanCss = cleanCss;
8exports.ruleTypes = exports.default = void 0;
9
10/*
11 * The MIT License (MIT)
12 *
13 * Copyright (c) 2015 - present Instructure, Inc.
14 *
15 * Permission is hereby granted, free of charge, to any person obtaining a copy
16 * of this software and associated documentation files (the "Software"), to deal
17 * in the Software without restriction, including without limitation the rights
18 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19 * copies of the Software, and to permit persons to whom the Software is
20 * furnished to do so, subject to the following conditions:
21 *
22 * The above copyright notice and this permission notice shall be included in all
23 * copies or substantial portions of the Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33
34/**
35 * ---
36 * category: utilities/themes
37 * ---
38 * Parses a CSS string into an AST object
39 * @module parseCss
40 * @param {String} cssText CSS string to parse
41 * @returns {Object} AST for the CSS string
42 */
43function parseCss() {
44 var cssText = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : '';
45 var cleaned = cleanCss(cssText);
46 return parseLexed(lex(cleaned), cleaned);
47}
48/**
49 * CSSRule types (https://developer.mozilla.org/en-US/docs/Web/API/CSSRule)
50 */
51
52
53var ruleTypes = {
54 style: 1,
55 keyframes: 7,
56 media: 4
57};
58/**
59 * Removes comments and import statements from a CSS string
60 * (to prep for parsing and applying transforms)
61 * @param {String} cssText CSS string to parse
62 * @returns {String} cleaned CSS string
63 */
64
65exports.ruleTypes = ruleTypes;
66
67function cleanCss() {
68 var text = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : '';
69 // remove comments and imports
70 return text.replace(/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim, '').replace(/@import[^;]*;/gim, '');
71}
72
73function lex(text) {
74 var rootNode = {
75 start: 0,
76 end: text.length
77 };
78 var node = rootNode;
79 var chars = text.split('');
80 chars.forEach(function (char, i) {
81 switch (char) {
82 case '{':
83 {
84 if (!node.rules) {
85 node.rules = [];
86 }
87
88 var parent = node;
89 var previous = parent.rules[parent.rules.length - 1];
90 node = {
91 start: i + 1,
92 parent: parent,
93 previous: previous
94 };
95 parent.rules.push(node);
96 break;
97 }
98
99 case '}':
100 {
101 node.end = i + 1;
102 node = node.parent || rootNode;
103 break;
104 }
105
106 default:
107 {
108 break;
109 }
110 }
111 });
112 return rootNode;
113}
114
115function parseSelector(node, text) {
116 var start = node.previous ? node.previous.end : node.parent.start;
117 var end = node.start - 1;
118 var selector = text.substring(start, end);
119 selector = selector.replace(/\s+/g, ' ');
120 selector = selector.substring(selector.lastIndexOf(';') + 1);
121 return selector.trim();
122}
123
124function parseRuleType(selector) {
125 if (selector.indexOf('@') === 0) {
126 if (selector.indexOf('@media') === 0) {
127 return ruleTypes.media;
128 } else if (selector.match(/^@[^\s]*keyframes/)) {
129 return ruleTypes.keyframes;
130 }
131 } else {
132 return ruleTypes.style;
133 }
134}
135
136function parseLexed(node) {
137 var text = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : '';
138
139 /* eslint-disable no-param-reassign */
140 if (node.parent) {
141 node.selector = parseSelector(node, text);
142 node.type = parseRuleType(node.selector);
143 }
144
145 node.cssText = text.substring(node.start, node.end - 1).trim();
146
147 if (node.rules && node.rules.length > 0) {
148 node.rules = node.rules.map(function (rule) {
149 return parseLexed(rule, text);
150 });
151 }
152 /* eslint-enable no-param-reassign */
153
154
155 return node;
156}
157
158var _default = parseCss;
159exports.default = _default;
\No newline at end of file