Skip to content

Commit 47cd0f0

Browse files
committed
accidental assignment #3
1 parent da88e3b commit 47cd0f0

File tree

25 files changed

+7630
-541
lines changed

25 files changed

+7630
-541
lines changed

dist/config.json.js

Lines changed: 708 additions & 0 deletions
Large diffs are not rendered by default.

dist/index-umd.js

Lines changed: 3408 additions & 0 deletions
Large diffs are not rendered by default.

dist/index-umd.min.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/parser/declaration/list.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { PropertySet } from './set.js';
2+
import { getConfig } from '../utils/config.js';
3+
import { PropertyMap } from './map.js';
4+
5+
const config = getConfig();
6+
class PropertyList {
7+
declarations;
8+
constructor() {
9+
this.declarations = new Map;
10+
}
11+
add(declaration) {
12+
if (declaration.typ != 'Declaration') {
13+
this.declarations.set(Number(Math.random().toString().slice(2)).toString(36), declaration);
14+
return this;
15+
}
16+
const propertyName = declaration.nam;
17+
if (propertyName in config.properties) {
18+
const shorthand = config.properties[propertyName].shorthand;
19+
if (!this.declarations.has(shorthand)) {
20+
this.declarations.set(shorthand, new PropertySet(config.properties[shorthand]));
21+
}
22+
this.declarations.get(shorthand).add(declaration);
23+
return this;
24+
}
25+
if (propertyName in config.map) {
26+
const shorthand = config.map[propertyName].shorthand;
27+
if (!this.declarations.has(shorthand)) {
28+
this.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
29+
}
30+
this.declarations.get(shorthand).add(declaration);
31+
return this;
32+
}
33+
this.declarations.set(propertyName, declaration);
34+
return this;
35+
}
36+
[Symbol.iterator]() {
37+
let iterator = this.declarations.values();
38+
const iterators = [];
39+
return {
40+
next() {
41+
let value = iterator.next();
42+
while ((value.done && iterators.length > 0) ||
43+
value.value instanceof PropertySet ||
44+
value.value instanceof PropertyMap) {
45+
if (value.value instanceof PropertySet || value.value instanceof PropertyMap) {
46+
iterators.unshift(iterator);
47+
// @ts-ignore
48+
iterator = value.value[Symbol.iterator]();
49+
value = iterator.next();
50+
}
51+
if (value.done && iterators.length > 0) {
52+
iterator = iterators.shift();
53+
value = iterator.next();
54+
}
55+
}
56+
return value;
57+
}
58+
};
59+
}
60+
}
61+
62+
export { PropertyList };

dist/parser/declaration/map.js

Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
import { eq } from '../utils/eq.js';
2+
import { isNumber } from '../utils/syntax.js';
3+
import { renderToken } from '../../renderer/renderer.js';
4+
import { matchType } from '../utils/type.js';
5+
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+
}
34+
class PropertyMap {
35+
config;
36+
declarations;
37+
requiredCount;
38+
pattern;
39+
constructor(config) {
40+
const values = Object.values(config.properties);
41+
this.requiredCount = values.reduce((acc, curr) => curr.required ? ++acc : acc, 0) || values.length;
42+
this.config = config;
43+
this.declarations = new Map;
44+
this.pattern = config.pattern.split(/\s/);
45+
}
46+
add(declaration) {
47+
if (declaration.nam == this.config.shorthand) {
48+
this.declarations.clear();
49+
this.declarations.set(declaration.nam, declaration);
50+
}
51+
else {
52+
const separator = this.config.separator;
53+
// expand shorthand
54+
if (declaration.nam != this.config.shorthand && this.declarations.has(this.config.shorthand)) {
55+
const tokens = {};
56+
const values = [];
57+
this.declarations.get(this.config.shorthand).val.slice().reduce((acc, curr) => {
58+
if (separator != null && separator.typ == curr.typ && eq(separator, curr)) {
59+
acc.push([]);
60+
return acc;
61+
}
62+
// else {
63+
acc.at(-1).push(curr);
64+
// }
65+
return acc;
66+
}, [[]]).reduce((acc, list, current) => {
67+
values.push(...this.pattern.reduce((acc, property) => {
68+
// let current: number = 0;
69+
const props = this.config.properties[property];
70+
for (let i = 0; i < acc.length; i++) {
71+
if (acc[i].typ == 'Comment' || acc[i].typ == 'Whitespace') {
72+
acc.splice(i, 1);
73+
i--;
74+
continue;
75+
}
76+
if (matchType(acc[i], props)) {
77+
if ('prefix' in props && props.previous != null && !(props.previous in tokens)) {
78+
return acc;
79+
}
80+
if (!(property in tokens)) {
81+
tokens[property] = [[acc[i]]];
82+
}
83+
else {
84+
if (current == tokens[property].length) {
85+
tokens[property].push([acc[i]]);
86+
// tokens[property][current].push();
87+
}
88+
else {
89+
tokens[property][current].push({ typ: 'Whitespace' }, acc[i]);
90+
}
91+
}
92+
acc.splice(i, 1);
93+
i--;
94+
// @ts-ignore
95+
if ('prefix' in props && acc[i]?.typ == props.prefix.typ) {
96+
// @ts-ignore
97+
if (eq(acc[i], this.config.properties[property].prefix)) {
98+
acc.splice(i, 1);
99+
i--;
100+
}
101+
}
102+
if (props.multiple) {
103+
continue;
104+
}
105+
return acc;
106+
}
107+
else {
108+
if (property in tokens && tokens[property].length > current) {
109+
return acc;
110+
}
111+
}
112+
}
113+
if (property in tokens && tokens[property].length > current) {
114+
return acc;
115+
}
116+
// default
117+
if (props.default.length > 0) {
118+
const defaults = parseString(props.default[0]);
119+
if (!(property in tokens)) {
120+
tokens[property] = [
121+
[...defaults
122+
]
123+
];
124+
}
125+
else {
126+
if (current == tokens[property].length) {
127+
tokens[property].push([]);
128+
tokens[property][current].push(...defaults);
129+
}
130+
else {
131+
tokens[property][current].push({ typ: 'Whitespace' }, ...defaults);
132+
}
133+
}
134+
}
135+
return acc;
136+
}, list));
137+
return values;
138+
}, []);
139+
if (values.length == 0) {
140+
this.declarations = Object.entries(tokens).reduce((acc, curr) => {
141+
acc.set(curr[0], {
142+
typ: 'Declaration',
143+
nam: curr[0],
144+
val: curr[1].reduce((acc, curr) => {
145+
if (acc.length > 0) {
146+
acc.push({ ...separator });
147+
}
148+
acc.push(...curr);
149+
return acc;
150+
}, [])
151+
});
152+
return acc;
153+
}, new Map);
154+
}
155+
}
156+
this.declarations.set(declaration.nam, declaration);
157+
}
158+
return this;
159+
}
160+
[Symbol.iterator]() {
161+
let requiredCount = Object.keys(this.config.properties).reduce((acc, curr) => this.declarations.has(curr) && this.config.properties[curr].required ? ++acc : acc, 0);
162+
if (requiredCount == 0) {
163+
requiredCount = this.declarations.size;
164+
}
165+
if (requiredCount < this.requiredCount) {
166+
return this.declarations.values();
167+
}
168+
let count = 0;
169+
const separator = this.config.separator;
170+
const tokens = {};
171+
// @ts-ignore
172+
const valid = Object.entries(this.config.properties).reduce((acc, curr) => {
173+
if (!this.declarations.has(curr[0])) {
174+
if (curr[1].required) {
175+
acc.push(curr[0]);
176+
}
177+
return acc;
178+
}
179+
let current = 0;
180+
const props = this.config.properties[curr[0]];
181+
// @ts-ignore
182+
for (const val of this.declarations.get(curr[0]).val) {
183+
if (separator != null && separator.typ == val.typ && eq(separator, val)) {
184+
current++;
185+
if (tokens[curr[0]].length == current) {
186+
tokens[curr[0]].push([]);
187+
}
188+
continue;
189+
}
190+
if (val.typ == 'Whitespace' || val.typ == 'Comment') {
191+
continue;
192+
}
193+
if (props.multiple && props.separator != null && props.separator.typ == val.typ && eq(val, props.separator)) {
194+
continue;
195+
}
196+
if (matchType(val, curr[1])) {
197+
if (!(curr[0] in tokens)) {
198+
tokens[curr[0]] = [[]];
199+
}
200+
// is default value
201+
tokens[curr[0]][current].push(val);
202+
continue;
203+
}
204+
acc.push(curr[0]);
205+
break;
206+
}
207+
if (count == 0) {
208+
count = current;
209+
}
210+
return acc;
211+
}, []);
212+
if (valid.length > 0 || Object.values(tokens).every(v => v.every(v => v.length == count))) {
213+
return this.declarations.values();
214+
}
215+
const values = Object.entries(tokens).reduce((acc, curr) => {
216+
const props = this.config.properties[curr[0]];
217+
for (let i = 0; i < curr[1].length; i++) {
218+
if (acc.length == i) {
219+
acc.push([]);
220+
}
221+
let values = curr[1][i].reduce((acc, curr) => {
222+
if (acc.length > 0) {
223+
acc.push({ typ: 'Whitespace' });
224+
}
225+
acc.push(curr);
226+
return acc;
227+
}, []);
228+
if (props.default.includes(curr[1][i].reduce((acc, curr) => acc + renderToken(curr) + ' ', '').trimEnd())) {
229+
continue;
230+
}
231+
values = values.filter((val) => {
232+
if (val.typ == 'Whitespace' || val.typ == 'Comment') {
233+
return false;
234+
}
235+
return !(val.typ == 'Iden' && props.default.includes(val.val));
236+
});
237+
if (values.length > 0) {
238+
if ('mapping' in props) {
239+
if (!('constraints' in props) || !('max' in props.constraints) || values.length <= props.constraints.mapping.max) {
240+
let i = values.length;
241+
while (i--) {
242+
if (values[i].typ == 'Iden' && values[i].val in props.mapping) {
243+
values.splice(i, 1, ...parseString(props.mapping[values[i].val]));
244+
}
245+
}
246+
}
247+
}
248+
if ('prefix' in props) {
249+
acc[i].push({ ...props.prefix });
250+
}
251+
else if (acc[i].length > 0) {
252+
acc[i].push({ typ: 'Whitespace' });
253+
}
254+
acc[i].push(...values.reduce((acc, curr) => {
255+
if (acc.length > 0) {
256+
acc.push({ ...(props.separator ?? { typ: 'Whitespace' }) });
257+
}
258+
acc.push(curr);
259+
return acc;
260+
}, []));
261+
}
262+
}
263+
return acc;
264+
}, []).reduce((acc, curr) => {
265+
if (acc.length > 0) {
266+
acc.push({ ...separator });
267+
}
268+
if (curr.length == 0) {
269+
curr.push(...this.config.default[0].split(/\s/).map(getTokenType).reduce((acc, curr) => {
270+
if (acc.length > 0) {
271+
acc.push({ typ: 'Whitespace' });
272+
}
273+
acc.push(curr);
274+
return acc;
275+
}, []));
276+
}
277+
acc.push(...curr);
278+
return acc;
279+
}, []);
280+
return [{
281+
typ: 'Declaration',
282+
nam: this.config.shorthand,
283+
val: values
284+
}][Symbol.iterator]();
285+
}
286+
}
287+
288+
export { PropertyMap };

0 commit comments

Comments
 (0)