Skip to content

Commit f6700b6

Browse files
authored
Merge pull request #88 from tbela99/feature/syntax_update
Feature/syntax update
2 parents 0df90e8 + 99d1360 commit f6700b6

File tree

28 files changed

+1649
-822
lines changed

28 files changed

+1649
-822
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## v1.1.1
4+
5+
- [x] fix validation issues
6+
37
## v1.1.0
48

59
- [x] inline sourcemap

dist/index-umd-web.js

Lines changed: 296 additions & 169 deletions
Large diffs are not rendered by default.

dist/index.cjs

Lines changed: 296 additions & 169 deletions
Large diffs are not rendered by default.

dist/index.d.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,17 @@
22
* validation level enum
33
*/
44
declare enum ValidationLevel {
5+
/**
6+
* disable validation
7+
*/
58
None = 0,
9+
/**
10+
* validate selectors and at-rules
11+
*/
612
Default = 1,// selectors + at-rules
13+
/**
14+
* validate selectors, at-rules and declarations
15+
*/
716
All = 2
817
}
918
/**
@@ -1160,6 +1169,7 @@ interface ValidationOptions {
11601169
interface MinifyOptions {
11611170

11621171
minify?: boolean;
1172+
parseColor?: boolean;
11631173
nestingRules?: boolean;
11641174
expandNestingRules?: boolean;
11651175
removeDuplicateDeclarations?: boolean;
@@ -1179,7 +1189,6 @@ export declare interface ParserOptions extends MinifyOptions, MinifyFeatureOptio
11791189
resolveUrls?: boolean;
11801190
resolveImport?: boolean;
11811191
cwd?: string;
1182-
parseColor?: boolean;
11831192
removePrefix?: boolean;
11841193
load?: (url: string, currentUrl: string) => Promise<string>;
11851194
dirname?: (path: string) => string;
@@ -1248,15 +1257,20 @@ export declare interface TransformOptions extends ParserOptions, RenderOptions {
12481257

12491258
}
12501259

1260+
export declare interface ParseResultStats {
1261+
src: string;
1262+
bytesIn: number;
1263+
importedBytesIn: number;
1264+
parse: string;
1265+
minify: string;
1266+
total: string;
1267+
imports: ParseResultStats[]
1268+
}
1269+
12511270
export declare interface ParseResult {
12521271
ast: AstRuleStyleSheet;
12531272
errors: ErrorDescription[];
1254-
stats: {
1255-
bytesIn: number;
1256-
parse: string;
1257-
minify: string;
1258-
total: string;
1259-
}
1273+
stats: ParseResultStats
12601274
}
12611275

12621276
export declare interface RenderResult {
@@ -1271,12 +1285,15 @@ export declare interface RenderResult {
12711285
export declare interface TransformResult extends ParseResult, RenderResult {
12721286

12731287
stats: {
1288+
src: string;
12741289
bytesIn: number;
12751290
bytesOut: number;
1291+
importedBytesIn: number;
12761292
parse: string;
12771293
minify: string;
12781294
render: string;
12791295
total: string;
1296+
imports: ParseResultStats[];
12801297
}
12811298
}
12821299

dist/lib/ast/types.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,17 @@ var SyntaxValidationResult;
99
*/
1010
var ValidationLevel;
1111
(function (ValidationLevel) {
12+
/**
13+
* disable validation
14+
*/
1215
ValidationLevel[ValidationLevel["None"] = 0] = "None";
16+
/**
17+
* validate selectors and at-rules
18+
*/
1319
ValidationLevel[ValidationLevel["Default"] = 1] = "Default";
20+
/**
21+
* validate selectors, at-rules and declarations
22+
*/
1423
ValidationLevel[ValidationLevel["All"] = 2] = "All"; // selectors + at-rules + declarations
1524
})(ValidationLevel || (ValidationLevel = {}));
1625
/**

dist/lib/ast/utils/utils.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import { funcLike, ColorKind } from '../../renderer/color/utils/constants.js';
2+
import { EnumToken } from '../types.js';
3+
import '../minify.js';
4+
import '../walk.js';
5+
import '../../parser/parse.js';
6+
import '../../parser/tokenize.js';
7+
import '../../parser/utils/config.js';
8+
import '../../renderer/sourcemap/lib/encode.js';
9+
import { minmax } from '../../renderer/color/color.js';
10+
11+
function reduceNumber(val) {
12+
val = String(+val);
13+
if (val === '0') {
14+
return '0';
15+
}
16+
const chr = val.charAt(0);
17+
if (chr == '-') {
18+
const slice = val.slice(0, 2);
19+
if (slice == '-0') {
20+
return val.length == 2 ? '0' : '-' + val.slice(2);
21+
}
22+
}
23+
if (chr == '0') {
24+
return val.slice(1);
25+
}
26+
return val;
27+
}
28+
/**
29+
* clamp color values
30+
* @param token
31+
*/
32+
function clamp(token) {
33+
if (token.kin == ColorKind.RGB || token.kin == ColorKind.RGBA) {
34+
token.chi.filter((token) => ![EnumToken.LiteralTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType].includes(token.typ)).forEach((token, index) => {
35+
if (index <= 2) {
36+
if (token.typ == EnumToken.NumberTokenType) {
37+
token.val = String(minmax(+token.val, 0, 255));
38+
}
39+
else if (token.typ == EnumToken.PercentageTokenType) {
40+
token.val = String(minmax(+token.val, 0, 100));
41+
}
42+
}
43+
else {
44+
if (token.typ == EnumToken.NumberTokenType) {
45+
token.val = String(minmax(+token.val, 0, 1));
46+
}
47+
else if (token.typ == EnumToken.PercentageTokenType) {
48+
token.val = String(minmax(+token.val, 0, 100));
49+
}
50+
}
51+
});
52+
}
53+
return token;
54+
}
55+
function getNumber(token) {
56+
if (token.typ == EnumToken.IdenTokenType && token.val == 'none') {
57+
return 0;
58+
}
59+
// @ts-ignore
60+
return token.typ == EnumToken.PercentageTokenType ? token.val / 100 : +token.val;
61+
}
62+
/**
63+
* convert angle to turn
64+
* @param token
65+
*/
66+
function getAngle(token) {
67+
if (token.typ == EnumToken.IdenTokenType) {
68+
if (token.val == 'none') {
69+
return 0;
70+
}
71+
}
72+
if (token.typ == EnumToken.AngleTokenType) {
73+
switch (token.unit) {
74+
case 'deg':
75+
// @ts-ignore
76+
return token.val / 360;
77+
case 'rad':
78+
// @ts-ignore
79+
return token.val / (2 * Math.PI);
80+
case 'grad':
81+
// @ts-ignore
82+
return token.val / 400;
83+
case 'turn':
84+
// @ts-ignore
85+
return +token.val;
86+
}
87+
}
88+
// @ts-ignore
89+
return token.val / 360;
90+
}
91+
function filterValues(values) {
92+
let i = 0;
93+
for (; i < values.length; i++) {
94+
if (values[i].typ == EnumToken.ImportantTokenType && values[i - 1]?.typ == EnumToken.WhitespaceTokenType) {
95+
values.splice(i - 1, 1);
96+
}
97+
else if (funcLike.includes(values[i].typ) && !['var', 'calc'].includes(values[i].val) && values[i + 1]?.typ == EnumToken.WhitespaceTokenType) {
98+
values.splice(i + 1, 1);
99+
}
100+
}
101+
return values;
102+
}
103+
104+
export { clamp, filterValues, getAngle, getNumber, reduceNumber };

dist/lib/parser/parse.js

Lines changed: 24 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,13 @@ async function doParse(iterator, options = {}) {
8383
const src = options.src;
8484
const stack = [];
8585
const stats = {
86+
src: options.src ?? '',
8687
bytesIn: 0,
8788
importedBytesIn: 0,
8889
parse: `0ms`,
8990
minify: `0ms`,
90-
total: `0ms`
91+
total: `0ms`,
92+
imports: []
9193
};
9294
let ast = {
9395
typ: EnumToken.StyleSheetNodeType,
@@ -133,7 +135,7 @@ async function doParse(iterator, options = {}) {
133135
ast.loc.end = item.end;
134136
}
135137
if (item.token == ';' || item.token == '{') {
136-
node = parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
138+
node = parseNode(tokens, context, options, errors, src, map, rawTokens);
137139
rawTokens.length = 0;
138140
if (node != null) {
139141
if ('chi' in node) {
@@ -172,7 +174,7 @@ async function doParse(iterator, options = {}) {
172174
map = new Map;
173175
}
174176
else if (item.token == '}') {
175-
parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
177+
parseNode(tokens, context, options, errors, src, map, rawTokens);
176178
rawTokens.length = 0;
177179
if (context.loc != null) {
178180
context.loc.end = item.end;
@@ -193,7 +195,7 @@ async function doParse(iterator, options = {}) {
193195
}
194196
}
195197
if (tokens.length > 0) {
196-
node = parseNode(tokens, context, stats, options, errors, src, map, rawTokens);
198+
node = parseNode(tokens, context, options, errors, src, map, rawTokens);
197199
rawTokens.length = 0;
198200
if (node != null) {
199201
if (node.typ == EnumToken.AtRuleNodeType && node.nam == 'import') {
@@ -218,14 +220,14 @@ async function doParse(iterator, options = {}) {
218220
const url = token.typ == EnumToken.StringTokenType ? token.val.slice(1, -1) : token.val;
219221
try {
220222
const root = await options.load(url, options.src).then((src) => {
221-
// console.error({url, src: options.src, resolved: options.resolve!(url, options.src as string)})
222223
return doParse(src, Object.assign({}, options, {
223224
minify: false,
224225
setParent: false,
225226
src: options.resolve(url, options.src).absolute
226227
}));
227228
});
228229
stats.importedBytesIn += root.stats.bytesIn;
230+
stats.imports.push(root.stats);
229231
node.parent.chi.splice(node.parent.chi.indexOf(node), 1, ...root.ast.chi);
230232
if (root.errors.length > 0) {
231233
errors.push(...root.errors);
@@ -317,7 +319,7 @@ function getLastNode(context) {
317319
}
318320
return null;
319321
}
320-
function parseNode(results, context, stats, options, errors, src, map, rawTokens) {
322+
function parseNode(results, context, options, errors, src, map, rawTokens) {
321323
let tokens = [];
322324
for (const t of results) {
323325
const node = getTokenType(t.token, t.hint);
@@ -545,9 +547,11 @@ function parseNode(results, context, stats, options, errors, src, map, rawTokens
545547
removeComments: true
546548
}), '');
547549
}
548-
// }
549550
context.chi.push(node);
550-
Object.defineProperties(node, { parent: { ...definedPropertySettings, value: context }, validSyntax: { ...definedPropertySettings, value: valid.valid == SyntaxValidationResult.Valid } });
551+
Object.defineProperties(node, {
552+
parent: { ...definedPropertySettings, value: context },
553+
validSyntax: { ...definedPropertySettings, value: valid.valid == SyntaxValidationResult.Valid }
554+
});
551555
return node;
552556
}
553557
else {
@@ -585,11 +589,9 @@ function parseNode(results, context, stats, options, errors, src, map, rawTokens
585589
let t = renderToken(curr, { minify: false });
586590
if (t == ',') {
587591
acc.push([]);
588-
// uniqTokens.push([]);
589592
}
590593
else {
591594
acc[acc.length - 1].push(t);
592-
// uniqTokens[uniqTokens.length - 1].push(curr);
593595
}
594596
return acc;
595597
}, [[]]).reduce((acc, curr) => {
@@ -621,7 +623,6 @@ function parseNode(results, context, stats, options, errors, src, map, rawTokens
621623
// @ts-ignore
622624
context.chi.push(node);
623625
Object.defineProperty(node, 'parent', { ...definedPropertySettings, value: context });
624-
// if (options.validation) {
625626
// @ts-ignore
626627
const valid = options.validation == ValidationLevel.None ? {
627628
valid: SyntaxValidationResult.Valid,
@@ -638,24 +639,10 @@ function parseNode(results, context, stats, options, errors, src, map, rawTokens
638639
location
639640
});
640641
}
641-
// } else {
642-
//
643-
// Object.defineProperty(node, 'tokens', {
644-
// ...definedPropertySettings,
645-
// enumerable: false,
646-
// value: tokens.slice()
647-
// });
648-
//
649-
// let raw: string[][] = [...uniq.values()];
650-
//
651-
// Object.defineProperty(node, 'raw', {
652-
// enumerable: false,
653-
// configurable: true,
654-
// writable: true,
655-
// value: raw
656-
// });
657-
// }
658-
Object.defineProperty(node, 'validSyntax', { ...definedPropertySettings, value: valid.valid == SyntaxValidationResult.Valid });
642+
Object.defineProperty(node, 'validSyntax', {
643+
...definedPropertySettings,
644+
value: valid.valid == SyntaxValidationResult.Valid
645+
});
659646
return node;
660647
}
661648
else {
@@ -705,9 +692,7 @@ function parseNode(results, context, stats, options, errors, src, map, rawTokens
705692
parseColor(tokens[i]);
706693
}
707694
}
708-
tokens.splice(i, 0, { typ: EnumToken.ColonTokenType });
709-
// i++;
710-
i--;
695+
tokens.splice(i--, 0, { typ: EnumToken.ColonTokenType });
711696
continue;
712697
}
713698
if ('chi' in tokens[i]) {
@@ -792,11 +777,15 @@ function parseNode(results, context, stats, options, errors, src, map, rawTokens
792777
const result = parseDeclarationNode(node, errors, location);
793778
Object.defineProperty(result, 'parent', { ...definedPropertySettings, value: context });
794779
if (result != null) {
795-
// console.error(doRender(result), result.val, location);
796780
if (options.validation == ValidationLevel.All) {
797781
const valid = evaluateSyntax(result, options);
798-
Object.defineProperty(result, 'validSyntax', { ...definedPropertySettings, value: valid.valid == SyntaxValidationResult.Valid });
782+
Object.defineProperty(result, 'validSyntax', {
783+
...definedPropertySettings,
784+
value: valid.valid == SyntaxValidationResult.Valid
785+
});
799786
if (valid.valid == SyntaxValidationResult.Drop) {
787+
// console.error({result, valid});
788+
// console.error(JSON.stringify({result, options, valid}, null, 1));
800789
errors.push({
801790
action: 'drop',
802791
message: valid.error,
@@ -1590,12 +1579,6 @@ function parseTokens(tokens, options = {}) {
15901579
if (t.chi[0].val.slice(1, 5) != 'data:' && urlTokenMatcher.test(value)) {
15911580
// @ts-ignore
15921581
t.chi[0].typ = EnumToken.UrlTokenTokenType;
1593-
// console.error({t, v: t.chi[0], value,
1594-
// src: options.src,
1595-
// resolved: options.src !== '' && options.resolveUrls ? options.resolve(value, options.src).absolute : null,
1596-
// val2: options.src !== '' && options.resolveUrls ? options.resolve(value, options.src).absolute : value});
1597-
//
1598-
// console.error(new Error('resolved'));
15991582
// @ts-ignore
16001583
t.chi[0].val = options.src !== '' && options.resolveUrls ? options.resolve(value, options.src).absolute : value;
16011584
}
@@ -1648,4 +1631,4 @@ function parseTokens(tokens, options = {}) {
16481631
return tokens;
16491632
}
16501633

1651-
export { doParse, parseAtRulePrelude, parseSelector, parseString, parseTokens, urlTokenMatcher };
1634+
export { doParse, getTokenType, parseAtRulePrelude, parseSelector, parseString, parseTokens, urlTokenMatcher };

0 commit comments

Comments
 (0)