diff --git a/packages/compiler-cli/src/ngcc/src/analysis/decoration_analyzer.ts b/packages/compiler-cli/src/ngcc/src/analysis/decoration_analyzer.ts index 75fb58bfc5..69ad987677 100644 --- a/packages/compiler-cli/src/ngcc/src/analysis/decoration_analyzer.ts +++ b/packages/compiler-cli/src/ngcc/src/analysis/decoration_analyzer.ts @@ -60,7 +60,7 @@ export class DecorationAnalyzer { new BaseDefDecoratorHandler(this.typeChecker, this.host), new ComponentDecoratorHandler( this.typeChecker, this.host, this.scopeRegistry, this.isCore, this.resourceLoader, - this.rootDirs), + this.rootDirs, /* defaultPreserveWhitespaces */ false), new DirectiveDecoratorHandler(this.typeChecker, this.host, this.scopeRegistry, this.isCore), new InjectableDecoratorHandler(this.host, this.isCore), new NgModuleDecoratorHandler(this.typeChecker, this.host, this.scopeRegistry, this.isCore), diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/component.ts b/packages/compiler-cli/src/ngtsc/annotations/src/component.ts index b803b7a2bb..a3bbbf896d 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/component.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/component.ts @@ -38,7 +38,8 @@ export class ComponentDecoratorHandler implements constructor( private checker: ts.TypeChecker, private reflector: ReflectionHost, private scopeRegistry: SelectorScopeRegistry, private isCore: boolean, - private resourceLoader: ResourceLoader, private rootDirs: string[]) {} + private resourceLoader: ResourceLoader, private rootDirs: string[], + private defaultPreserveWhitespaces: boolean) {} private literalCache = new Map(); private elementSchemaRegistry = new DomElementSchemaRegistry(); @@ -111,7 +112,7 @@ export class ComponentDecoratorHandler implements ErrorCode.COMPONENT_MISSING_TEMPLATE, decorator.node, 'component is missing a template'); } - let preserveWhitespaces: boolean = false; + let preserveWhitespaces: boolean = this.defaultPreserveWhitespaces; if (component.has('preserveWhitespaces')) { const expr = component.get('preserveWhitespaces') !; const value = staticallyResolve(expr, this.reflector, this.checker); diff --git a/packages/compiler-cli/src/ngtsc/annotations/test/component_spec.ts b/packages/compiler-cli/src/ngtsc/annotations/test/component_spec.ts index 4decbfdde9..ffa02def51 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/test/component_spec.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/test/component_spec.ts @@ -40,7 +40,7 @@ describe('ComponentDecoratorHandler', () => { const host = new TypeScriptReflectionHost(checker); const handler = new ComponentDecoratorHandler( checker, host, new SelectorScopeRegistry(checker, host), false, new NoopResourceLoader(), - ['']); + [''], false); const TestCmp = getDeclaration(program, 'entry.ts', 'TestCmp', ts.isClassDeclaration); const detected = handler.detect(TestCmp, host.getDecoratorsOfDeclaration(TestCmp)); if (detected === undefined) { diff --git a/packages/compiler-cli/src/ngtsc/program.ts b/packages/compiler-cli/src/ngtsc/program.ts index c925718dca..9ea3ba656f 100644 --- a/packages/compiler-cli/src/ngtsc/program.ts +++ b/packages/compiler-cli/src/ngtsc/program.ts @@ -219,7 +219,8 @@ export class NgtscProgram implements api.Program { const handlers = [ new BaseDefDecoratorHandler(checker, this.reflector), new ComponentDecoratorHandler( - checker, this.reflector, scopeRegistry, this.isCore, this.resourceLoader, this.rootDirs), + checker, this.reflector, scopeRegistry, this.isCore, this.resourceLoader, this.rootDirs, + this.options.preserveWhitespaces || false), new DirectiveDecoratorHandler(checker, this.reflector, scopeRegistry, this.isCore), new InjectableDecoratorHandler(this.reflector, this.isCore), new NgModuleDecoratorHandler(checker, this.reflector, scopeRegistry, this.isCore), diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 8b159bb2c1..a7d1bd4c73 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -553,6 +553,46 @@ describe('ngtsc behavioral tests', () => { expect(trim(jsContents)).toContain(trim(hostBindingsFn)); }); + it('should take preserveWhitespaces config option into account', () => { + env.tsconfig({preserveWhitespaces: true}); + env.write(`test.ts`, ` + import {Component} from '@angular/core'; + @Component({ + selector: 'test', + template: \` +
+ Template with whitespaces +
+ \` + }) + class FooCmp {} + `); + env.driveMain(); + const jsContents = env.getContents('test.js'); + expect(jsContents) + .toContain('text(2, "\\n Template with whitespaces\\n ");'); + }); + + it('@Component\'s preserveWhitespaces should override the one defined in config', () => { + env.tsconfig({preserveWhitespaces: true}); + env.write(`test.ts`, ` + import {Component} from '@angular/core'; + @Component({ + selector: 'test', + preserveWhitespaces: false, + template: \` +
+ Template with whitespaces +
+ \` + }) + class FooCmp {} + `); + env.driveMain(); + const jsContents = env.getContents('test.js'); + expect(jsContents).toContain('text(1, " Template with whitespaces ");'); + }); + it('should correctly recognize local symbols', () => { env.tsconfig(); env.write('module.ts', `