angular-cn/modules/@angular/compiler/src/style_compiler.ts

96 lines
3.7 KiB
TypeScript
Raw Normal View History

/**
* @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 {Injectable, ViewEncapsulation} from '@angular/core';
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileStylesheetMetadata, identifierModuleUrl, identifierName} from './compile_metadata';
import * as o from './output/output_ast';
import {ShadowCss} from './shadow_css';
import {UrlResolver} from './url_resolver';
const COMPONENT_VARIABLE = '%COMP%';
2016-07-13 14:01:32 -04:00
const HOST_ATTR = `_nghost-${COMPONENT_VARIABLE}`;
const CONTENT_ATTR = `_ngcontent-${COMPONENT_VARIABLE}`;
export class StylesCompileDependency {
constructor(
public name: string, public moduleUrl: string, public isShimmed: boolean,
public valuePlaceholder: CompileIdentifierMetadata) {}
}
export class StylesCompileResult {
constructor(
public componentStylesheet: CompiledStylesheet,
public externalStylesheets: CompiledStylesheet[]) {}
}
export class CompiledStylesheet {
constructor(
public statements: o.Statement[], public stylesVar: string,
public dependencies: StylesCompileDependency[], public isShimmed: boolean,
public meta: CompileStylesheetMetadata) {}
}
@Injectable()
export class StyleCompiler {
private _shadowCss: ShadowCss = new ShadowCss();
constructor(private _urlResolver: UrlResolver) {}
compileComponent(comp: CompileDirectiveMetadata): StylesCompileResult {
2016-07-09 13:12:39 -04:00
const externalStylesheets: CompiledStylesheet[] = [];
const componentStylesheet: CompiledStylesheet = this._compileStyles(
comp, new CompileStylesheetMetadata({
styles: comp.template.styles,
styleUrls: comp.template.styleUrls,
moduleUrl: identifierModuleUrl(comp.type)
}),
true);
comp.template.externalStylesheets.forEach((stylesheetMeta) => {
2016-07-09 13:12:39 -04:00
const compiledStylesheet = this._compileStyles(comp, stylesheetMeta, false);
externalStylesheets.push(compiledStylesheet);
});
return new StylesCompileResult(componentStylesheet, externalStylesheets);
}
private _compileStyles(
comp: CompileDirectiveMetadata, stylesheet: CompileStylesheetMetadata,
isComponentStylesheet: boolean): CompiledStylesheet {
2016-07-09 13:12:39 -04:00
const shim = comp.template.encapsulation === ViewEncapsulation.Emulated;
const styleExpressions =
stylesheet.styles.map(plainStyle => o.literal(this._shimIfNeeded(plainStyle, shim)));
2016-07-09 13:12:39 -04:00
const dependencies: StylesCompileDependency[] = [];
for (let i = 0; i < stylesheet.styleUrls.length; i++) {
const identifier: CompileIdentifierMetadata = {reference: null};
dependencies.push(new StylesCompileDependency(
getStylesVarName(null), stylesheet.styleUrls[i], shim, identifier));
styleExpressions.push(new o.ExternalExpr(identifier));
}
// styles variable contains plain strings and arrays of other styles arrays (recursive),
// so we set its type to dynamic.
2016-07-09 13:12:39 -04:00
const stylesVar = getStylesVarName(isComponentStylesheet ? comp : null);
const stmt = o.variable(stylesVar)
.set(o.literalArr(
styleExpressions, new o.ArrayType(o.DYNAMIC_TYPE, [o.TypeModifier.Const])))
.toDeclStmt(null, [o.StmtModifier.Final]);
return new CompiledStylesheet([stmt], stylesVar, dependencies, shim, stylesheet);
}
private _shimIfNeeded(style: string, shim: boolean): string {
return shim ? this._shadowCss.shimCssText(style, CONTENT_ATTR, HOST_ATTR) : style;
}
}
function getStylesVarName(component: CompileDirectiveMetadata): string {
2016-07-09 13:12:39 -04:00
let result = `styles`;
if (component) {
result += `_${identifierName(component.type)}`;
}
return result;
}