@tbela99/css-parser 0.0.1-alpha4 → 0.0.1-rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@ function* doWalk(node, parent, root) {
6
6
  yield { node, parent, root };
7
7
  if ('chi' in node) {
8
8
  for (const child of node.chi) {
9
- yield* doWalk(child, node, (root == null ? node : root));
9
+ yield* doWalk(child, node, (root ?? node));
10
10
  }
11
11
  }
12
12
  }
@@ -1,6 +1,7 @@
1
1
  import { PropertySet } from './set.js';
2
2
  import { getConfig } from '../utils/config.js';
3
3
  import { PropertyMap } from './map.js';
4
+ import { parseString } from '../parse.js';
4
5
 
5
6
  const config = getConfig();
6
7
  class PropertyList {
@@ -8,33 +9,61 @@ class PropertyList {
8
9
  constructor() {
9
10
  this.declarations = new Map;
10
11
  }
12
+ set(nam, value) {
13
+ return this.add({ typ: 'Declaration', nam, val: Array.isArray(value) ? value : parseString(String(value)) });
14
+ }
11
15
  add(declaration) {
12
16
  if (declaration.typ != 'Declaration') {
13
17
  this.declarations.set(Number(Math.random().toString().slice(2)).toString(36), declaration);
14
18
  return this;
15
19
  }
16
- const propertyName = declaration.nam;
20
+ let propertyName = declaration.nam;
21
+ let shortHandType;
22
+ let shorthand;
17
23
  if (propertyName in config.properties) {
18
24
  // @ts-ignore
19
- const shorthand = config.properties[propertyName].shorthand;
25
+ if ('map' in config.properties[propertyName]) {
26
+ shortHandType = 'map';
27
+ // @ts-ignore
28
+ shorthand = config.properties[propertyName].map;
29
+ }
30
+ else {
31
+ shortHandType = 'set';
32
+ // @ts-ignore
33
+ shorthand = config.properties[propertyName].shorthand;
34
+ }
35
+ }
36
+ else if (propertyName in config.map) {
37
+ shortHandType = 'map';
38
+ // @ts-ignore
39
+ shorthand = config.map[propertyName].shorthand;
40
+ }
41
+ // @ts-ignore
42
+ if (shortHandType == 'map') {
43
+ // @ts-ignore
20
44
  if (!this.declarations.has(shorthand)) {
21
45
  // @ts-ignore
22
- this.declarations.set(shorthand, new PropertySet(config.properties[shorthand]));
46
+ this.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
23
47
  }
48
+ // @ts-ignore
24
49
  this.declarations.get(shorthand).add(declaration);
25
- return this;
50
+ // return this;
26
51
  }
27
- if (propertyName in config.map) {
52
+ // @ts-ignore
53
+ else if (shortHandType == 'set') {
28
54
  // @ts-ignore
29
- const shorthand = config.map[propertyName].shorthand;
55
+ // const shorthand: string = <string>config.properties[propertyName].shorthand;
30
56
  if (!this.declarations.has(shorthand)) {
31
57
  // @ts-ignore
32
- this.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
58
+ this.declarations.set(shorthand, new PropertySet(config.properties[shorthand]));
33
59
  }
60
+ // @ts-ignore
34
61
  this.declarations.get(shorthand).add(declaration);
35
- return this;
62
+ // return this;
63
+ }
64
+ else {
65
+ this.declarations.set(propertyName, declaration);
36
66
  }
37
- this.declarations.set(propertyName, declaration);
38
67
  return this;
39
68
  }
40
69
  [Symbol.iterator]() {
@@ -1,36 +1,11 @@
1
1
  import { eq } from '../utils/eq.js';
2
- import { isNumber } from '../utils/syntax.js';
2
+ import { getConfig } from '../utils/config.js';
3
3
  import { renderToken } from '../../renderer/render.js';
4
4
  import { matchType } from '../utils/type.js';
5
+ import { parseString } from '../parse.js';
6
+ import { PropertySet } from './set.js';
5
7
 
6
- function getTokenType(val) {
7
- if (val == 'transparent' || val == 'currentcolor') {
8
- return {
9
- typ: 'Color',
10
- val,
11
- kin: 'lit'
12
- };
13
- }
14
- if (val.endsWith('%')) {
15
- return {
16
- typ: 'Perc',
17
- val: val.slice(0, -1)
18
- };
19
- }
20
- return {
21
- typ: isNumber(val) ? 'Number' : 'Iden',
22
- val
23
- };
24
- }
25
- function parseString(val) {
26
- return val.split(/\s/).map(getTokenType).reduce((acc, curr) => {
27
- if (acc.length > 0) {
28
- acc.push({ typ: 'Whitespace' });
29
- }
30
- acc.push(curr);
31
- return acc;
32
- }, []);
33
- }
8
+ const propertiesConfig = getConfig();
34
9
  class PropertyMap {
35
10
  config;
36
11
  declarations;
@@ -45,7 +20,7 @@ class PropertyMap {
45
20
  }
46
21
  add(declaration) {
47
22
  if (declaration.nam == this.config.shorthand) {
48
- this.declarations.clear();
23
+ this.declarations = new Map;
49
24
  this.declarations.set(declaration.nam, declaration);
50
25
  }
51
26
  else {
@@ -122,8 +97,7 @@ class PropertyMap {
122
97
  const defaults = parseString(props.default[0]);
123
98
  if (!(property in tokens)) {
124
99
  tokens[property] = [
125
- [...defaults
126
- ]
100
+ [...defaults]
127
101
  ];
128
102
  }
129
103
  else {
@@ -157,145 +131,229 @@ class PropertyMap {
157
131
  }, new Map);
158
132
  }
159
133
  }
160
- this.declarations.set(declaration.nam, declaration);
134
+ // @ts-ignore
135
+ const config = propertiesConfig.properties[declaration.nam];
136
+ let property = declaration.nam;
137
+ if (config != null) {
138
+ property = config.shorthand;
139
+ let value = this.declarations.get(property);
140
+ if (!(value instanceof PropertySet)) {
141
+ // @ts-ignore
142
+ this.declarations.set(property, new PropertySet(propertiesConfig.properties[config.shorthand]));
143
+ // Token[]
144
+ if (value != null) {
145
+ // @ts-ignore
146
+ this.declarations.get(property).add(value);
147
+ }
148
+ }
149
+ this.declarations.get(property).add(declaration);
150
+ }
151
+ else {
152
+ this.declarations.set(declaration.nam, declaration);
153
+ }
161
154
  }
162
155
  return this;
163
156
  }
164
157
  [Symbol.iterator]() {
165
- let requiredCount = Object.keys(this.config.properties).reduce((acc, curr) => this.declarations.has(curr) && this.config.properties[curr].required ? ++acc : acc, 0);
166
- if (requiredCount == 0) {
167
- requiredCount = this.declarations.size;
168
- }
169
- if (requiredCount < this.requiredCount) {
170
- // if (this.declarations.size == 1 && this.declarations.has(this.config.shorthand)) {
171
- //
172
- // this.declarations
173
- // }
174
- return this.declarations.values();
175
- }
176
- let count = 0;
177
- const separator = this.config.separator;
178
- const tokens = {};
179
- // @ts-ignore
180
- const valid = Object.entries(this.config.properties).reduce((acc, curr) => {
181
- if (!this.declarations.has(curr[0])) {
182
- if (curr[1].required) {
183
- acc.push(curr[0]);
158
+ let iterable;
159
+ let requiredCount = 0;
160
+ let property;
161
+ let isShorthand = true;
162
+ for (property of Object.keys(this.config.properties)) {
163
+ if (this.config.properties[property].required) {
164
+ if (!this.declarations.has(property)) {
165
+ isShorthand = false;
166
+ break;
184
167
  }
185
- return acc;
186
- }
187
- let current = 0;
188
- const props = this.config.properties[curr[0]];
189
- // @ts-ignore
190
- for (const val of this.declarations.get(curr[0]).val) {
191
- if (separator != null && separator.typ == val.typ && eq(separator, val)) {
192
- current++;
193
- if (tokens[curr[0]].length == current) {
194
- tokens[curr[0]].push([]);
168
+ else {
169
+ const val = this.declarations.get(property);
170
+ if (val instanceof PropertySet && !val.isShortHand()) {
171
+ isShorthand = false;
172
+ break;
195
173
  }
196
- continue;
197
- }
198
- if (val.typ == 'Whitespace' || val.typ == 'Comment') {
199
- continue;
200
- }
201
- if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(val, props.separator)) {
202
- continue;
203
- }
204
- if (matchType(val, curr[1])) {
205
- if (!(curr[0] in tokens)) {
206
- tokens[curr[0]] = [[]];
174
+ else {
175
+ requiredCount++;
207
176
  }
208
- // is default value
209
- tokens[curr[0]][current].push(val);
210
- continue;
211
177
  }
212
- acc.push(curr[0]);
213
- break;
214
178
  }
215
- if (count == 0) {
216
- count = current;
217
- }
218
- return acc;
219
- }, []);
220
- if (valid.length > 0 || Object.values(tokens).every(v => v.every(v => v.length == count))) {
221
- return this.declarations.values();
222
179
  }
223
- const values = Object.entries(tokens).reduce((acc, curr) => {
224
- const props = this.config.properties[curr[0]];
225
- for (let i = 0; i < curr[1].length; i++) {
226
- if (acc.length == i) {
227
- acc.push([]);
228
- }
229
- let values = curr[1][i].reduce((acc, curr) => {
230
- if (acc.length > 0) {
231
- acc.push({ typ: 'Whitespace' });
180
+ if (requiredCount == 0) {
181
+ requiredCount = this.declarations.size;
182
+ }
183
+ if (!isShorthand || requiredCount < this.requiredCount) {
184
+ // @ts-ignore
185
+ iterable = this.declarations.values();
186
+ }
187
+ else {
188
+ let count = 0;
189
+ const separator = this.config.separator;
190
+ const tokens = {};
191
+ // @ts-ignore
192
+ /* const valid: string[] =*/ Object.entries(this.config.properties).reduce((acc, curr) => {
193
+ if (!this.declarations.has(curr[0])) {
194
+ if (curr[1].required) {
195
+ acc.push(curr[0]);
232
196
  }
233
- acc.push(curr);
234
197
  return acc;
235
- }, []);
236
- if (props.default.includes(curr[1][i].reduce((acc, curr) => acc + renderToken(curr) + ' ', '').trimEnd())) {
237
- continue;
238
198
  }
239
- values = values.filter((val) => {
199
+ let current = 0;
200
+ const props = this.config.properties[curr[0]];
201
+ const declaration = this.declarations.get(curr[0]);
202
+ // @ts-ignore
203
+ for (const val of (declaration instanceof PropertySet ? [...declaration][0] : declaration).val) {
204
+ if (separator != null && separator.typ == val.typ && eq(separator, val)) {
205
+ current++;
206
+ if (tokens[curr[0]].length == current) {
207
+ tokens[curr[0]].push([]);
208
+ }
209
+ continue;
210
+ }
240
211
  if (val.typ == 'Whitespace' || val.typ == 'Comment') {
241
- return false;
212
+ continue;
242
213
  }
243
- return !(val.typ == 'Iden' && props.default.includes(val.val));
244
- });
245
- if (values.length > 0) {
246
- if ('mapping' in props) {
247
- // @ts-ignore
248
- if (!('constraints' in props) || !('max' in props.constraints) || values.length <= props.constraints.mapping.max) {
249
- let i = values.length;
250
- while (i--) {
214
+ if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(props.separator, val)) {
215
+ continue;
216
+ }
217
+ if (matchType(val, curr[1])) {
218
+ if (!(curr[0] in tokens)) {
219
+ tokens[curr[0]] = [[]];
220
+ }
221
+ // is default value
222
+ tokens[curr[0]][current].push(val);
223
+ // continue;
224
+ }
225
+ else {
226
+ acc.push(curr[0]);
227
+ break;
228
+ }
229
+ }
230
+ if (count == 0) {
231
+ count = current;
232
+ }
233
+ return acc;
234
+ }, []);
235
+ count++;
236
+ if (!Object.values(tokens).every(v => v.length == count)) {
237
+ // @ts-ignore
238
+ iterable = this.declarations.values();
239
+ }
240
+ else {
241
+ const values = Object.entries(tokens).reduce((acc, curr) => {
242
+ const props = this.config.properties[curr[0]];
243
+ for (let i = 0; i < curr[1].length; i++) {
244
+ if (acc.length == i) {
245
+ acc.push([]);
246
+ }
247
+ let values = curr[1][i].reduce((acc, curr) => {
248
+ if (acc.length > 0) {
249
+ acc.push({ typ: 'Whitespace' });
250
+ }
251
+ acc.push(curr);
252
+ return acc;
253
+ }, []);
254
+ // @todo remove renderToken call
255
+ if (props.default.includes(curr[1][i].reduce((acc, curr) => acc + renderToken(curr) + ' ', '').trimEnd())) {
256
+ continue;
257
+ }
258
+ let doFilterDefault = true;
259
+ if (curr[0] in propertiesConfig.properties) {
260
+ for (let v of values) {
261
+ if (!['Whitespace', 'Comment', 'Iden'].includes(v.typ)
262
+ || (v.typ == 'Iden' && !this.config.properties[curr[0]].default.includes(v.val))) {
263
+ doFilterDefault = false;
264
+ break;
265
+ }
266
+ }
267
+ }
268
+ // remove default values
269
+ values = values.filter((val) => {
270
+ if (val.typ == 'Whitespace' || val.typ == 'Comment') {
271
+ return false;
272
+ }
273
+ return !doFilterDefault || !(val.typ == 'Iden' && props.default.includes(val.val));
274
+ });
275
+ if (values.length > 0) {
276
+ if ('mapping' in props) {
251
277
  // @ts-ignore
252
- if (values[i].typ == 'Iden' && values[i].val in props.mapping) {
253
- // @ts-ignore
254
- values.splice(i, 1, ...parseString(props.mapping[values[i].val]));
278
+ if (!('constraints' in props) || !('max' in props.constraints) || values.length <= props.constraints.mapping.max) {
279
+ let i = values.length;
280
+ while (i--) {
281
+ // @ts-ignore
282
+ if (values[i].typ == 'Iden' && values[i].val in props.mapping) {
283
+ // @ts-ignore
284
+ values.splice(i, 1, ...parseString(props.mapping[values[i].val]));
285
+ }
286
+ }
255
287
  }
256
288
  }
289
+ if ('prefix' in props) {
290
+ // @ts-ignore
291
+ acc[i].push({ ...props.prefix });
292
+ }
293
+ else if (acc[i].length > 0) {
294
+ acc[i].push({ typ: 'Whitespace' });
295
+ }
296
+ acc[i].push(...values.reduce((acc, curr) => {
297
+ if (acc.length > 0) {
298
+ // @ts-ignore
299
+ acc.push({ ...(props.separator ?? { typ: 'Whitespace' }) });
300
+ }
301
+ // @ts-ignore
302
+ acc.push(curr);
303
+ return acc;
304
+ }, []));
257
305
  }
258
306
  }
259
- if ('prefix' in props) {
260
- // @ts-ignore
261
- acc[i].push({ ...props.prefix });
307
+ return acc;
308
+ }, []).reduce((acc, curr) => {
309
+ if (acc.length > 0) {
310
+ acc.push({ ...separator });
262
311
  }
263
- else if (acc[i].length > 0) {
264
- acc[i].push({ typ: 'Whitespace' });
312
+ if (curr.length == 0 && this.config.default.length > 0) {
313
+ curr.push(...parseString(this.config.default[0]).reduce((acc, curr) => {
314
+ if (acc.length > 0) {
315
+ acc.push({ typ: 'Whitespace' });
316
+ }
317
+ acc.push(curr);
318
+ return acc;
319
+ }, []));
265
320
  }
266
- acc[i].push(...values.reduce((acc, curr) => {
267
- if (acc.length > 0) {
321
+ acc.push(...curr);
322
+ return acc;
323
+ }, []);
324
+ iterable = [{
325
+ typ: 'Declaration',
326
+ nam: this.config.shorthand,
327
+ val: values
328
+ }][Symbol.iterator]();
329
+ }
330
+ }
331
+ const iterators = [];
332
+ return {
333
+ // @ts-ignore
334
+ next() {
335
+ let v = iterable.next();
336
+ while (v.done || v.value instanceof PropertySet) {
337
+ if (v.value instanceof PropertySet) {
338
+ // @ts-ignore
339
+ iterators.push(iterable);
340
+ iterable = v.value[Symbol.iterator]();
341
+ v = iterable.next();
342
+ }
343
+ if (v.done) {
344
+ if (iterators.length > 0) {
268
345
  // @ts-ignore
269
- acc.push({ ...(props.separator ?? { typ: 'Whitespace' }) });
346
+ iterable = iterators.pop();
347
+ v = iterable.next();
348
+ }
349
+ if (v.done && iterators.length == 0) {
350
+ break;
270
351
  }
271
- // @ts-ignore
272
- acc.push(curr);
273
- return acc;
274
- }, []));
275
- }
276
- }
277
- return acc;
278
- }, []).reduce((acc, curr) => {
279
- if (acc.length > 0) {
280
- acc.push({ ...separator });
281
- }
282
- if (curr.length == 0) {
283
- curr.push(...this.config.default[0].split(/\s/).map(getTokenType).reduce((acc, curr) => {
284
- if (acc.length > 0) {
285
- acc.push({ typ: 'Whitespace' });
286
352
  }
287
- acc.push(curr);
288
- return acc;
289
- }, []));
353
+ }
354
+ return v;
290
355
  }
291
- acc.push(...curr);
292
- return acc;
293
- }, []);
294
- return [{
295
- typ: 'Declaration',
296
- nam: this.config.shorthand,
297
- val: values
298
- }][Symbol.iterator]();
356
+ };
299
357
  }
300
358
  }
301
359
 
@@ -10,8 +10,7 @@ class PropertySet {
10
10
  }
11
11
  add(declaration) {
12
12
  if (declaration.nam == this.config.shorthand) {
13
- this.declarations.clear();
14
- this.declarations.set(declaration.nam, declaration);
13
+ this.declarations = new Map;
15
14
  }
16
15
  else {
17
16
  // expand shorthand
@@ -34,6 +33,10 @@ class PropertySet {
34
33
  }
35
34
  if (token.typ != 'Whitespace' && token.typ != 'Comment') {
36
35
  if (token.typ == 'Iden' && this.config.keywords.includes(token.val)) {
36
+ if (tokens.length == 0) {
37
+ tokens.push([]);
38
+ current++;
39
+ }
37
40
  tokens[current].push(token);
38
41
  }
39
42
  if (token.typ == 'Literal' && token.val == this.config.separator) {
@@ -49,10 +52,6 @@ class PropertySet {
49
52
  this.declarations.delete(this.config.shorthand);
50
53
  for (const values of tokens) {
51
54
  this.config.properties.forEach((property, index) => {
52
- // if (property == declaration.nam) {
53
- //
54
- // return;
55
- // }
56
55
  if (!this.declarations.has(property)) {
57
56
  this.declarations.set(property, {
58
57
  typ: 'Declaration',
@@ -81,30 +80,20 @@ class PropertySet {
81
80
  this.declarations.set(declaration.nam, declaration);
82
81
  return this;
83
82
  }
84
- // declaration.chi = declaration.chi.reduce((acc: Token[], token: Token) => {
85
- //
86
- // if (this.config.types.includes(token.typ) || ('0' == (<DimensionToken>token).chi && (
87
- // this.config.types.includes('Length') ||
88
- // this.config.types.includes('Angle') ||
89
- // this.config.types.includes('Dimension'))) || (token.typ == 'Iden' && this.config.keywords.includes(token.chi))) {
90
- //
91
- // acc.push(token);
92
- // }
93
- //
94
- // return acc;
95
- // }, <Token[]>[]);
96
- this.declarations.set(declaration.nam, declaration);
97
83
  }
84
+ this.declarations.set(declaration.nam, declaration);
98
85
  return this;
99
86
  }
87
+ isShortHand() {
88
+ if (this.declarations.has(this.config.shorthand)) {
89
+ return this.declarations.size == 1;
90
+ }
91
+ return this.config.properties.length == this.declarations.size;
92
+ }
100
93
  [Symbol.iterator]() {
101
94
  let iterator;
102
95
  const declarations = this.declarations;
103
- if (declarations.size < this.config.properties.length || this.config.properties.some((property, index) => {
104
- return !declarations.has(property) || (index > 0 &&
105
- // @ts-ignore
106
- declarations.get(property).val.length != declarations.get(this.config.properties[Math.floor(index / 2)]).val.length);
107
- })) {
96
+ if (declarations.size < this.config.properties.length) {
108
97
  iterator = declarations.values();
109
98
  }
110
99
  else {
@@ -162,17 +151,20 @@ class PropertySet {
162
151
  return acc;
163
152
  }, [])
164
153
  }][Symbol.iterator]();
165
- return {
166
- next() {
167
- return iterator.next();
168
- }
169
- };
154
+ // return {
155
+ // next() {
156
+ //
157
+ // return iterator.next();
158
+ // }
159
+ // }
170
160
  }
171
- return {
172
- next() {
173
- return iterator.next();
174
- }
175
- };
161
+ return iterator;
162
+ // return {
163
+ // next() {
164
+ //
165
+ // return iterator.next();
166
+ // }
167
+ // }
176
168
  }
177
169
  }
178
170