forked from angular/angular
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(upgrade): fix downgrade content projection and injector inheritance
- Full support for content projection in downgraded Angular 2 components. In particular, this enables multi-slot projection and other features on <ng-content>. - Correctly wire up hierarchical injectors for downgraded Angular 2 components: downgraded components inherit the injector of the first other downgraded Angular 2 component they find up the DOM tree. Closes angular#6629, angular#7727, angular#8729, angular#9643, angular#9649
- Loading branch information
1 parent
aa8509c
commit 71d8609
Showing
8 changed files
with
465 additions
and
184 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* @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 {CompilerFactory, PlatformRef, Provider, createPlatformFactory} from '@angular/core'; | ||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; | ||
import {CapturedContentSelectors, RuntimeCompilerSpyFactory} from './runtime_compiler_spy'; | ||
|
||
const INTERNAL_UPGRADE_PLATFORM_PROVIDERS: Provider[] = | ||
[CapturedContentSelectors, {provide: CompilerFactory, useClass: RuntimeCompilerSpyFactory}]; | ||
|
||
/** | ||
* A custom platform for the UpgradeAdapter, which includes additional helper services | ||
* such as the `CapturedContentSelectors` collection and a monkeypatched version of the | ||
* `CompilerFactory`. | ||
* | ||
* @experimental | ||
*/ | ||
export const platformUpgrade = | ||
createPlatformFactory(platformBrowserDynamic, 'upgrade', INTERNAL_UPGRADE_PLATFORM_PROVIDERS); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/** | ||
* @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 {RuntimeCompilerFactory} from '@angular/compiler'; | ||
import {COMPILER_OPTIONS, Compiler, CompilerOptions, Inject, Injectable} from '@angular/core'; | ||
|
||
/** | ||
* This class is a map from each component`s selector to that component's `ngContent` selectors. | ||
* @internal | ||
*/ | ||
export class CapturedContentSelectors { | ||
private items: {[componentSelector: string]: string[]} = {}; | ||
set(componentSelector: string, ngContentSelectors: string[]) { | ||
this.items[componentSelector] = ngContentSelectors; | ||
} | ||
get(componentSelector: string): string[] { return this.items[componentSelector]; } | ||
} | ||
|
||
/** | ||
* We need to capture all the `ngContent` selectors for each downgraded component so that | ||
* we can correctly project the content onto them. | ||
* We do this by monkeypatching the `Compiler` with our own version that spies upon the | ||
* compiled templates and captures all the `ngContent` selectors. | ||
* @internal | ||
*/ | ||
@Injectable() | ||
export class RuntimeCompilerSpyFactory extends RuntimeCompilerFactory { | ||
constructor( | ||
@Inject(COMPILER_OPTIONS) defaultOptions: CompilerOptions[], | ||
private contentSelectors: CapturedContentSelectors) { | ||
super(defaultOptions); | ||
} | ||
createCompiler(options: CompilerOptions[] = []): Compiler { | ||
// Very ugly hack to get access to the compiler's internal objects. | ||
// Better here than in the compiler module itself, though. | ||
const contentSelectors = this.contentSelectors; | ||
let runtimeCompiler: any = <any>super.createCompiler(options); | ||
let originalCompileTemplate = runtimeCompiler._compileTemplate; | ||
runtimeCompiler._compileTemplate = function(template: any) { | ||
if (!template.isCompiled && !template.isHost) { | ||
const metadata = template.compMeta; | ||
if (metadata.template && metadata.template.ngContentSelectors) { | ||
contentSelectors.set(metadata.selector, metadata.template.ngContentSelectors); | ||
} | ||
} | ||
return originalCompileTemplate.call(this, template); | ||
}; | ||
return runtimeCompiler; | ||
} | ||
} |
Oops, something went wrong.