2015-09-18 13:33:23 -04:00
|
|
|
import {CompileTypeMetadata, CompileTemplateMetadata} from './directive_metadata';
|
2015-09-14 18:59:09 -04:00
|
|
|
import {SourceModule, SourceExpression, moduleRef} from './source_module';
|
2015-10-05 13:10:07 -04:00
|
|
|
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
|
2015-11-05 17:07:57 -05:00
|
|
|
import {XHR} from 'angular2/src/compiler/xhr';
|
2015-11-06 20:34:07 -05:00
|
|
|
import {IS_DART, StringWrapper, isBlank} from 'angular2/src/facade/lang';
|
|
|
|
import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
|
2015-11-05 17:07:57 -05:00
|
|
|
import {ShadowCss} from 'angular2/src/compiler/shadow_css';
|
|
|
|
import {UrlResolver} from 'angular2/src/compiler/url_resolver';
|
2015-10-14 12:39:40 -04:00
|
|
|
import {extractStyleUrls} from './style_url_resolver';
|
2015-09-14 18:59:09 -04:00
|
|
|
import {
|
|
|
|
escapeSingleQuoteString,
|
2015-09-28 13:30:33 -04:00
|
|
|
codeGenExportVariable,
|
2015-10-01 13:07:49 -04:00
|
|
|
codeGenToString,
|
|
|
|
MODULE_SUFFIX
|
2015-09-14 18:59:09 -04:00
|
|
|
} from './util';
|
|
|
|
import {Injectable} from 'angular2/src/core/di';
|
2015-12-02 13:35:51 -05:00
|
|
|
|
|
|
|
const COMPONENT_VARIABLE = '%COMP%';
|
|
|
|
const HOST_ATTR = `_nghost-${COMPONENT_VARIABLE}`;
|
|
|
|
const CONTENT_ATTR = `_ngcontent-${COMPONENT_VARIABLE}`;
|
2015-09-02 18:07:31 -04:00
|
|
|
|
2015-09-14 18:59:09 -04:00
|
|
|
@Injectable()
|
2015-09-02 18:07:31 -04:00
|
|
|
export class StyleCompiler {
|
|
|
|
private _styleCache: Map<string, Promise<string[]>> = new Map<string, Promise<string[]>>();
|
|
|
|
private _shadowCss: ShadowCss = new ShadowCss();
|
|
|
|
|
|
|
|
constructor(private _xhr: XHR, private _urlResolver: UrlResolver) {}
|
|
|
|
|
2015-11-02 11:39:14 -05:00
|
|
|
compileComponentRuntime(template: CompileTemplateMetadata): Promise<Array<string | any[]>> {
|
2015-09-18 13:33:23 -04:00
|
|
|
var styles = template.styles;
|
|
|
|
var styleAbsUrls = template.styleUrls;
|
2015-09-02 18:07:31 -04:00
|
|
|
return this._loadStyles(styles, styleAbsUrls,
|
2015-11-02 11:39:14 -05:00
|
|
|
template.encapsulation === ViewEncapsulation.Emulated);
|
2015-09-02 18:07:31 -04:00
|
|
|
}
|
|
|
|
|
2015-11-02 11:39:14 -05:00
|
|
|
compileComponentCodeGen(template: CompileTemplateMetadata): SourceExpression {
|
2015-09-18 13:33:23 -04:00
|
|
|
var shim = template.encapsulation === ViewEncapsulation.Emulated;
|
2015-11-02 11:39:14 -05:00
|
|
|
return this._styleCodeGen(template.styles, template.styleUrls, shim);
|
2015-09-02 18:07:31 -04:00
|
|
|
}
|
|
|
|
|
2015-10-01 13:07:49 -04:00
|
|
|
compileStylesheetCodeGen(stylesheetUrl: string, cssText: string): SourceModule[] {
|
2015-10-14 12:39:40 -04:00
|
|
|
var styleWithImports = extractStyleUrls(this._urlResolver, stylesheetUrl, cssText);
|
2015-09-02 18:07:31 -04:00
|
|
|
return [
|
2015-10-01 13:07:49 -04:00
|
|
|
this._styleModule(
|
|
|
|
stylesheetUrl, false,
|
2015-11-02 11:39:14 -05:00
|
|
|
this._styleCodeGen([styleWithImports.style], styleWithImports.styleUrls, false)),
|
|
|
|
this._styleModule(stylesheetUrl, true, this._styleCodeGen([styleWithImports.style],
|
|
|
|
styleWithImports.styleUrls, true))
|
2015-09-02 18:07:31 -04:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2015-09-18 13:33:23 -04:00
|
|
|
clearCache() { this._styleCache.clear(); }
|
|
|
|
|
2015-09-02 18:07:31 -04:00
|
|
|
private _loadStyles(plainStyles: string[], absUrls: string[],
|
2015-11-02 11:39:14 -05:00
|
|
|
encapsulate: boolean): Promise<Array<string | any[]>> {
|
2015-09-02 18:07:31 -04:00
|
|
|
var promises = absUrls.map((absUrl) => {
|
|
|
|
var cacheKey = `${absUrl}${encapsulate ? '.shim' : ''}`;
|
|
|
|
var result = this._styleCache.get(cacheKey);
|
|
|
|
if (isBlank(result)) {
|
|
|
|
result = this._xhr.get(absUrl).then((style) => {
|
2015-10-14 12:39:40 -04:00
|
|
|
var styleWithImports = extractStyleUrls(this._urlResolver, absUrl, style);
|
2015-09-02 18:07:31 -04:00
|
|
|
return this._loadStyles([styleWithImports.style], styleWithImports.styleUrls,
|
|
|
|
encapsulate);
|
|
|
|
});
|
|
|
|
this._styleCache.set(cacheKey, result);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
});
|
|
|
|
return PromiseWrapper.all(promises).then((nestedStyles: string[][]) => {
|
2015-11-02 11:39:14 -05:00
|
|
|
var result: Array<string | any[]> =
|
|
|
|
plainStyles.map(plainStyle => this._shimIfNeeded(plainStyle, encapsulate));
|
|
|
|
nestedStyles.forEach(styles => result.push(styles));
|
2015-09-02 18:07:31 -04:00
|
|
|
return result;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-11-02 11:39:14 -05:00
|
|
|
private _styleCodeGen(plainStyles: string[], absUrls: string[], shim: boolean): SourceExpression {
|
|
|
|
var arrayPrefix = IS_DART ? `const` : '';
|
|
|
|
var styleExpressions = plainStyles.map(
|
|
|
|
plainStyle => escapeSingleQuoteString(this._shimIfNeeded(plainStyle, shim)));
|
|
|
|
|
2015-09-02 18:07:31 -04:00
|
|
|
for (var i = 0; i < absUrls.length; i++) {
|
2015-10-01 13:07:49 -04:00
|
|
|
var moduleUrl = this._createModuleUrl(absUrls[i], shim);
|
2015-11-02 11:39:14 -05:00
|
|
|
styleExpressions.push(`${moduleRef(moduleUrl)}STYLES`);
|
2015-09-02 18:07:31 -04:00
|
|
|
}
|
2015-11-02 11:39:14 -05:00
|
|
|
var expressionSource = `${arrayPrefix} [${styleExpressions.join(',')}]`;
|
2015-09-14 18:59:09 -04:00
|
|
|
return new SourceExpression([], expressionSource);
|
|
|
|
}
|
|
|
|
|
2015-10-01 13:07:49 -04:00
|
|
|
private _styleModule(stylesheetUrl: string, shim: boolean,
|
2015-09-14 18:59:09 -04:00
|
|
|
expression: SourceExpression): SourceModule {
|
|
|
|
var moduleSource = `
|
|
|
|
${expression.declarations.join('\n')}
|
|
|
|
${codeGenExportVariable('STYLES')}${expression.expression};
|
|
|
|
`;
|
2015-10-01 13:07:49 -04:00
|
|
|
return new SourceModule(this._createModuleUrl(stylesheetUrl, shim), moduleSource);
|
2015-09-02 18:07:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
private _shimIfNeeded(style: string, shim: boolean): string {
|
|
|
|
return shim ? this._shadowCss.shimCssText(style, CONTENT_ATTR, HOST_ATTR) : style;
|
|
|
|
}
|
|
|
|
|
2015-10-01 13:07:49 -04:00
|
|
|
private _createModuleUrl(stylesheetUrl: string, shim: boolean): string {
|
|
|
|
return shim ? `${stylesheetUrl}.shim${MODULE_SUFFIX}` : `${stylesheetUrl}${MODULE_SUFFIX}`;
|
2015-09-02 18:07:31 -04:00
|
|
|
}
|
|
|
|
}
|