1 | 'use strict';
|
2 |
|
3 |
|
4 | function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
5 |
|
6 | function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
7 |
|
8 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
9 |
|
10 | var nothingHappend = {
|
11 | prop: {},
|
12 | eaten: ''
|
13 | };
|
14 | var defaultConfig = {
|
15 | defaultValue: function defaultValue() {
|
16 | return undefined;
|
17 | }
|
18 |
|
19 | };
|
20 |
|
21 | function parse(value, indexNext, userConfig) {
|
22 |
|
23 | var letsEat = '';
|
24 | var stopOnBrace = false;
|
25 | var errorDetected = false;
|
26 |
|
27 | var config = _objectSpread({}, defaultConfig, {}, userConfig);
|
28 |
|
29 |
|
30 | if (typeof config.defaultValue !== 'function') {
|
31 | var defaultValue = config.defaultValue;
|
32 |
|
33 | config.defaultValue = function () {
|
34 | return defaultValue;
|
35 | };
|
36 | }
|
37 |
|
38 | var prop = {};
|
39 |
|
40 |
|
41 | |
42 |
|
43 |
|
44 | var labelFirst = '';
|
45 | var labelSecond;
|
46 |
|
47 | if (indexNext === undefined) {
|
48 | indexNext = 0;
|
49 | }
|
50 | |
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | var type;
|
60 | var forbidenCharacters = '\n\r{}';
|
61 |
|
62 | var shouldStop = function shouldStop() {
|
63 | if (indexNext >= value.length || forbidenCharacters.indexOf(value[indexNext]) > -1) {
|
64 | if (stopOnBrace && value[indexNext] !== '}') {
|
65 | errorDetected = true;
|
66 | }
|
67 |
|
68 | return true;
|
69 | }
|
70 |
|
71 | return value[indexNext] === '}' && stopOnBrace;
|
72 | };
|
73 |
|
74 | var eaten = '';
|
75 |
|
76 |
|
77 | var eat = function eat(chars) {
|
78 | eaten = '';
|
79 |
|
80 | while (indexNext < value.length && forbidenCharacters.indexOf(value.charAt(indexNext)) < 0 && chars.indexOf(value.charAt(indexNext)) >= 0) {
|
81 | letsEat += value.charAt(indexNext);
|
82 | eaten += value.charAt(indexNext);
|
83 | indexNext++;
|
84 | }
|
85 |
|
86 | return shouldStop();
|
87 | };
|
88 |
|
89 | var eatUntil = function eatUntil(chars) {
|
90 | eaten = '';
|
91 |
|
92 | while (indexNext < value.length && forbidenCharacters.indexOf(value.charAt(indexNext)) < 0 && chars.indexOf(value.charAt(indexNext)) < 0) {
|
93 | letsEat += value.charAt(indexNext);
|
94 | eaten += value.charAt(indexNext);
|
95 | indexNext++;
|
96 | }
|
97 |
|
98 |
|
99 |
|
100 | if (labelFirst) {
|
101 | labelSecond = eaten;
|
102 | } else {
|
103 | labelFirst = eaten;
|
104 | }
|
105 |
|
106 | return shouldStop();
|
107 | };
|
108 |
|
109 |
|
110 |
|
111 | var eatInQuote = function eatInQuote(quote) {
|
112 | eaten = '';
|
113 |
|
114 | if (value[indexNext] === quote) {
|
115 | return;
|
116 | }
|
117 |
|
118 | while (indexNext < value.length && !(quote === value[indexNext] && value[indexNext - 1] !== '\\') && value[indexNext] !== '\n' && value[indexNext] !== '\r') {
|
119 | letsEat += value.charAt(indexNext);
|
120 | eaten += value.charAt(indexNext);
|
121 | indexNext++;
|
122 | }
|
123 |
|
124 |
|
125 |
|
126 | if (value[indexNext] === '\n' || value[indexNext] === '\r' || indexNext >= value.length) {
|
127 | errorDetected = true;
|
128 | return true;
|
129 | }
|
130 |
|
131 |
|
132 | if (labelFirst) {
|
133 | labelSecond = eaten.replace(/\\"/g, '"');
|
134 | } else {
|
135 | labelFirst = eaten.replace(/\\"/g, '"');
|
136 | }
|
137 |
|
138 | return shouldStop();
|
139 | };
|
140 |
|
141 |
|
142 | var eatOne = function eatOne(c, skipStopCheck) {
|
143 |
|
144 | letsEat += c;
|
145 | indexNext++;
|
146 | return skipStopCheck ? false : shouldStop();
|
147 | };
|
148 |
|
149 |
|
150 | var eatQuote = function eatQuote(q) {
|
151 | eatOne(q, true);
|
152 | eatInQuote(q, true);
|
153 |
|
154 | if (value.charAt(indexNext) !== q) {
|
155 | return nothingHappend;
|
156 | }
|
157 |
|
158 | if (eatOne(q)) {
|
159 | return -1;
|
160 | }
|
161 | };
|
162 |
|
163 | var idSetByKey = false;
|
164 |
|
165 | var addAttribute = function addAttribute() {
|
166 | switch (type) {
|
167 | case 'id':
|
168 |
|
169 | if (idSetByKey) {
|
170 | prop.id = labelFirst;
|
171 | idSetByKey = false;
|
172 | } else {
|
173 | prop.id = prop.id || labelFirst;
|
174 | }
|
175 |
|
176 | break;
|
177 |
|
178 | case 'class':
|
179 | if (!prop["class"]) {
|
180 | prop["class"] = [];
|
181 | }
|
182 |
|
183 | if (prop["class"].indexOf(labelFirst) < 0) {
|
184 | prop["class"].push(labelFirst);
|
185 | }
|
186 |
|
187 | break;
|
188 |
|
189 | case 'key':
|
190 | if (!labelFirst) {
|
191 | return nothingHappend;
|
192 | }
|
193 |
|
194 | if (!(labelFirst in prop)) {
|
195 | if (labelSecond === undefined) {
|
196 |
|
197 |
|
198 | prop[labelFirst] = config.defaultValue(labelFirst);
|
199 | } else {
|
200 | prop[labelFirst] = labelFirst === 'class' ? [labelSecond] : labelSecond;
|
201 | }
|
202 |
|
203 | if (labelFirst === 'id') {
|
204 | idSetByKey = true;
|
205 | }
|
206 | } else if (labelFirst === 'class' && Boolean(labelSecond)) {
|
207 | prop["class"].push(labelSecond);
|
208 | }
|
209 |
|
210 | break;
|
211 |
|
212 | default:
|
213 | }
|
214 |
|
215 | type = undefined;
|
216 | labelFirst = '';
|
217 | labelSecond = undefined;
|
218 | };
|
219 |
|
220 |
|
221 |
|
222 |
|
223 | eat(' \t\v');
|
224 |
|
225 | if (value[indexNext] === '{') {
|
226 | eatOne('{');
|
227 | stopOnBrace = true;
|
228 | }
|
229 |
|
230 | while (!shouldStop()) {
|
231 |
|
232 | if (eat(' \t\v')) {
|
233 | break;
|
234 | }
|
235 |
|
236 | if (value.charAt(indexNext) === '.') {
|
237 |
|
238 | type = 'class';
|
239 |
|
240 | if (eatOne('.')) {
|
241 | errorDetected = true;
|
242 | break;
|
243 | }
|
244 | } else if (value.charAt(indexNext) === '#') {
|
245 |
|
246 | type = 'id';
|
247 |
|
248 | if (eatOne('#')) {
|
249 | errorDetected = true;
|
250 | break;
|
251 | }
|
252 | } else {
|
253 |
|
254 | type = 'key';
|
255 | }
|
256 |
|
257 |
|
258 | if (eatUntil('=\t\b\v ') || !labelFirst) {
|
259 | break;
|
260 | }
|
261 |
|
262 | if (value.charAt(indexNext) === '=' && type === 'key') {
|
263 |
|
264 | if (eatOne('=')) {
|
265 | break;
|
266 | }
|
267 |
|
268 | if (value.charAt(indexNext) === '"') {
|
269 | var ret = eatQuote('"');
|
270 |
|
271 | if (ret === -1) {
|
272 | break;
|
273 | } else if (ret === nothingHappend) {
|
274 | return nothingHappend;
|
275 | }
|
276 | } else if (value.charAt(indexNext) === '\'') {
|
277 | var _ret = eatQuote('\'');
|
278 |
|
279 | if (_ret === -1) {
|
280 | break;
|
281 | } else if (_ret === nothingHappend) {
|
282 | return nothingHappend;
|
283 | }
|
284 | } else if (eatUntil(' \t\n\r\v=}')) {
|
285 | break;
|
286 | }
|
287 | }
|
288 |
|
289 |
|
290 | addAttribute();
|
291 | }
|
292 |
|
293 | addAttribute();
|
294 |
|
295 | if (stopOnBrace) {
|
296 | if (indexNext < value.length && value[indexNext] === '}') {
|
297 | stopOnBrace = false;
|
298 | eatOne('}');
|
299 | } else {
|
300 | return nothingHappend;
|
301 | }
|
302 | }
|
303 |
|
304 | return errorDetected ? nothingHappend : {
|
305 | prop: prop,
|
306 | eaten: letsEat
|
307 | };
|
308 | }
|
309 |
|
310 | module.exports = parse; |
\ | No newline at end of file |