-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathCSSNativeScript.ts
More file actions
122 lines (109 loc) · 2.96 KB
/
CSSNativeScript.ts
File metadata and controls
122 lines (109 loc) · 2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { InputToken, Stylesheet, Rule, AtRule, QualifiedRule } from './CSS3Parser';
/**
* Consume a CSS3 parsed stylesheet and convert the rules and selectors to the
* NativeScript internal JSON representation.
*/
export class CSSNativeScript {
public parseStylesheet(stylesheet: Stylesheet): any {
return {
type: 'stylesheet',
stylesheet: {
rules: this.parseRules(stylesheet.rules),
},
};
}
private parseRules(rules: Rule[]): any {
return rules.map((rule) => this.parseRule(rule));
}
private parseRule(rule: Rule): any {
if (rule.type === 'at-rule') {
return this.parseAtRule(rule);
} else if (rule.type === 'qualified-rule') {
return this.parseQualifiedRule(rule);
}
}
private parseAtRule(rule: AtRule): any {
if (rule.name === 'import') {
// TODO: We have used an "@import { url('path somewhere'); }" at few places.
return {
import: rule.prelude
.map((m) => (typeof m === 'string' ? m : m.text))
.join('')
.trim(),
type: 'import',
};
}
return;
}
private parseQualifiedRule(rule: QualifiedRule): any {
return {
type: 'rule',
selectors: this.preludeToSelectorsStringArray(rule.prelude),
declarations: this.ruleBlockToDeclarations(rule.block.values),
};
}
private ruleBlockToDeclarations(declarationsInputTokens: InputToken[]): { type: 'declaration'; property: string; value: string }[] {
// return <any>declarationsInputTokens;
const declarations: {
type: 'declaration';
property: string;
value: string;
}[] = [];
let property = '';
let value = '';
let reading: 'property' | 'value' = 'property';
for (let i = 0; i < declarationsInputTokens.length; i++) {
const inputToken = declarationsInputTokens[i];
if (reading === 'property') {
if (inputToken === ':') {
reading = 'value';
} else if (typeof inputToken === 'string') {
property += inputToken;
} else {
property += inputToken.text;
}
} else {
if (inputToken === ';') {
property = property.trim();
value = value.trim();
declarations.push({ type: 'declaration', property, value });
property = '';
value = '';
reading = 'property';
} else if (typeof inputToken === 'string') {
value += inputToken;
} else {
value += inputToken.text;
}
}
}
property = property.trim();
value = value.trim();
if (property || value) {
declarations.push({ type: 'declaration', property, value });
}
return declarations;
}
private preludeToSelectorsStringArray(prelude: InputToken[]): string[] {
const selectors = [];
let selector = '';
prelude.forEach((inputToken) => {
if (typeof inputToken === 'string') {
if (inputToken === ',') {
if (selector) {
selectors.push(selector.trim());
}
selector = '';
} else {
selector += inputToken;
}
} else if (typeof inputToken === 'object') {
selector += inputToken.text;
}
});
if (selector) {
selectors.push(selector.trim());
}
return selectors;
}
}