mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 02:54:11 +08:00
feat(core): make css parsers tree-shakable (#9496)
This commit is contained in:

committed by
Nathan Walker

parent
3e2e5dfe9d
commit
dd5f24a737
122
packages/core/css/CSSNativeScript.ts
Normal file
122
packages/core/css/CSSNativeScript.ts
Normal file
@ -0,0 +1,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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user