refactor: move angular source to /packages rather than modules/@angular
This commit is contained in:
248
packages/compiler/src/css_parser/css_ast.ts
Normal file
248
packages/compiler/src/css_parser/css_ast.ts
Normal file
@ -0,0 +1,248 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ParseLocation, ParseSourceSpan} from '../parse_util';
|
||||
|
||||
import {CssToken, CssTokenType} from './css_lexer';
|
||||
|
||||
export enum BlockType {
|
||||
Import,
|
||||
Charset,
|
||||
Namespace,
|
||||
Supports,
|
||||
Keyframes,
|
||||
MediaQuery,
|
||||
Selector,
|
||||
FontFace,
|
||||
Page,
|
||||
Document,
|
||||
Viewport,
|
||||
Unsupported
|
||||
}
|
||||
|
||||
export interface CssAstVisitor {
|
||||
visitCssValue(ast: CssStyleValueAst, context?: any): any;
|
||||
visitCssInlineRule(ast: CssInlineRuleAst, context?: any): any;
|
||||
visitCssAtRulePredicate(ast: CssAtRulePredicateAst, context?: any): any;
|
||||
visitCssKeyframeRule(ast: CssKeyframeRuleAst, context?: any): any;
|
||||
visitCssKeyframeDefinition(ast: CssKeyframeDefinitionAst, context?: any): any;
|
||||
visitCssMediaQueryRule(ast: CssMediaQueryRuleAst, context?: any): any;
|
||||
visitCssSelectorRule(ast: CssSelectorRuleAst, context?: any): any;
|
||||
visitCssSelector(ast: CssSelectorAst, context?: any): any;
|
||||
visitCssSimpleSelector(ast: CssSimpleSelectorAst, context?: any): any;
|
||||
visitCssPseudoSelector(ast: CssPseudoSelectorAst, context?: any): any;
|
||||
visitCssDefinition(ast: CssDefinitionAst, context?: any): any;
|
||||
visitCssBlock(ast: CssBlockAst, context?: any): any;
|
||||
visitCssStylesBlock(ast: CssStylesBlockAst, context?: any): any;
|
||||
visitCssStyleSheet(ast: CssStyleSheetAst, context?: any): any;
|
||||
visitCssUnknownRule(ast: CssUnknownRuleAst, context?: any): any;
|
||||
visitCssUnknownTokenList(ast: CssUnknownTokenListAst, context?: any): any;
|
||||
}
|
||||
|
||||
export abstract class CssAst {
|
||||
constructor(public location: ParseSourceSpan) {}
|
||||
get start(): ParseLocation { return this.location.start; }
|
||||
get end(): ParseLocation { return this.location.end; }
|
||||
abstract visit(visitor: CssAstVisitor, context?: any): any;
|
||||
}
|
||||
|
||||
export class CssStyleValueAst extends CssAst {
|
||||
constructor(location: ParseSourceSpan, public tokens: CssToken[], public strValue: string) {
|
||||
super(location);
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any { return visitor.visitCssValue(this); }
|
||||
}
|
||||
|
||||
export abstract class CssRuleAst extends CssAst {
|
||||
constructor(location: ParseSourceSpan) { super(location); }
|
||||
}
|
||||
|
||||
export class CssBlockRuleAst extends CssRuleAst {
|
||||
constructor(
|
||||
public location: ParseSourceSpan, public type: BlockType, public block: CssBlockAst,
|
||||
public name: CssToken = null) {
|
||||
super(location);
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssBlock(this.block, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssKeyframeRuleAst extends CssBlockRuleAst {
|
||||
constructor(location: ParseSourceSpan, name: CssToken, block: CssBlockAst) {
|
||||
super(location, BlockType.Keyframes, block, name);
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssKeyframeRule(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssKeyframeDefinitionAst extends CssBlockRuleAst {
|
||||
constructor(location: ParseSourceSpan, public steps: CssToken[], block: CssBlockAst) {
|
||||
super(location, BlockType.Keyframes, block, mergeTokens(steps, ','));
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssKeyframeDefinition(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssBlockDefinitionRuleAst extends CssBlockRuleAst {
|
||||
constructor(
|
||||
location: ParseSourceSpan, public strValue: string, type: BlockType,
|
||||
public query: CssAtRulePredicateAst, block: CssBlockAst) {
|
||||
super(location, type, block);
|
||||
const firstCssToken: CssToken = query.tokens[0];
|
||||
this.name = new CssToken(
|
||||
firstCssToken.index, firstCssToken.column, firstCssToken.line, CssTokenType.Identifier,
|
||||
this.strValue);
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssBlock(this.block, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssMediaQueryRuleAst extends CssBlockDefinitionRuleAst {
|
||||
constructor(
|
||||
location: ParseSourceSpan, strValue: string, query: CssAtRulePredicateAst,
|
||||
block: CssBlockAst) {
|
||||
super(location, strValue, BlockType.MediaQuery, query, block);
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssMediaQueryRule(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssAtRulePredicateAst extends CssAst {
|
||||
constructor(location: ParseSourceSpan, public strValue: string, public tokens: CssToken[]) {
|
||||
super(location);
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssAtRulePredicate(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssInlineRuleAst extends CssRuleAst {
|
||||
constructor(location: ParseSourceSpan, public type: BlockType, public value: CssStyleValueAst) {
|
||||
super(location);
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssInlineRule(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssSelectorRuleAst extends CssBlockRuleAst {
|
||||
public strValue: string;
|
||||
|
||||
constructor(location: ParseSourceSpan, public selectors: CssSelectorAst[], block: CssBlockAst) {
|
||||
super(location, BlockType.Selector, block);
|
||||
this.strValue = selectors.map(selector => selector.strValue).join(',');
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssSelectorRule(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssDefinitionAst extends CssAst {
|
||||
constructor(
|
||||
location: ParseSourceSpan, public property: CssToken, public value: CssStyleValueAst) {
|
||||
super(location);
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssDefinition(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class CssSelectorPartAst extends CssAst {
|
||||
constructor(location: ParseSourceSpan) { super(location); }
|
||||
}
|
||||
|
||||
export class CssSelectorAst extends CssSelectorPartAst {
|
||||
public strValue: string;
|
||||
constructor(location: ParseSourceSpan, public selectorParts: CssSimpleSelectorAst[]) {
|
||||
super(location);
|
||||
this.strValue = selectorParts.map(part => part.strValue).join('');
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssSelector(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssSimpleSelectorAst extends CssSelectorPartAst {
|
||||
constructor(
|
||||
location: ParseSourceSpan, public tokens: CssToken[], public strValue: string,
|
||||
public pseudoSelectors: CssPseudoSelectorAst[], public operator: CssToken) {
|
||||
super(location);
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssSimpleSelector(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssPseudoSelectorAst extends CssSelectorPartAst {
|
||||
constructor(
|
||||
location: ParseSourceSpan, public strValue: string, public name: string,
|
||||
public tokens: CssToken[], public innerSelectors: CssSelectorAst[]) {
|
||||
super(location);
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssPseudoSelector(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssBlockAst extends CssAst {
|
||||
constructor(location: ParseSourceSpan, public entries: CssAst[]) { super(location); }
|
||||
visit(visitor: CssAstVisitor, context?: any): any { return visitor.visitCssBlock(this, context); }
|
||||
}
|
||||
|
||||
/*
|
||||
a style block is different from a standard block because it contains
|
||||
css prop:value definitions. A regular block can contain a list of Ast entries.
|
||||
*/
|
||||
export class CssStylesBlockAst extends CssBlockAst {
|
||||
constructor(location: ParseSourceSpan, public definitions: CssDefinitionAst[]) {
|
||||
super(location, definitions);
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssStylesBlock(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssStyleSheetAst extends CssAst {
|
||||
constructor(location: ParseSourceSpan, public rules: CssAst[]) { super(location); }
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssStyleSheet(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssUnknownRuleAst extends CssRuleAst {
|
||||
constructor(location: ParseSourceSpan, public ruleName: string, public tokens: CssToken[]) {
|
||||
super(location);
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssUnknownRule(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export class CssUnknownTokenListAst extends CssRuleAst {
|
||||
constructor(location: ParseSourceSpan, public name: string, public tokens: CssToken[]) {
|
||||
super(location);
|
||||
}
|
||||
visit(visitor: CssAstVisitor, context?: any): any {
|
||||
return visitor.visitCssUnknownTokenList(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export function mergeTokens(tokens: CssToken[], separator: string = ''): CssToken {
|
||||
const mainToken = tokens[0];
|
||||
let str = mainToken.strValue;
|
||||
for (let i = 1; i < tokens.length; i++) {
|
||||
str += separator + tokens[i].strValue;
|
||||
}
|
||||
|
||||
return new CssToken(mainToken.index, mainToken.column, mainToken.line, mainToken.type, str);
|
||||
}
|
Reference in New Issue
Block a user