-
Notifications
You must be signed in to change notification settings - Fork 25.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(upgrade): support multi-slot projection in upgrade/static #14282
feat(upgrade): support multi-slot projection in upgrade/static #14282
Conversation
* | ||
* The `inputs` and `outputs` are strings that map the names of properties to camelCased | ||
* attribute names. They are of the form `"prop: attr"`; or simply `"propAndAttr" where the | ||
* property and attribute have the same identifier. | ||
* | ||
* The `selectors` are the strings that appear in the `ng-content` element's `select` attribute. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe: element's select
attribute --> elements' select
attributes
@@ -0,0 +1,94 @@ | |||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming the file _adapter_
instead of _adaptor_
would be more consistent with the class name 😉
const selectorHelper = new NgContentSelectorHelper(); | ||
const fakeInjector = {get: function() { return selectorHelper; }}; | ||
return new DowngradeComponentAdapter( | ||
'id', {component: null, selectors}, content, null, null, null, fakeInjector, null, null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too much mocking here (Travis complains) 😃
DowngradeComponentAdapter
creates the componentScope
in the constructor, so it needs a $scope
with a $new
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or not enough mocking!
d929037
to
6e4d98d
Compare
So there's good news and bad news. 👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there. 😕 The bad news is that it appears that one or more commits were authored by someone other than the pull request submitter. We need to confirm that they're okay with their commits being contributed to this project. Please have them confirm that here in the pull request. Note to project maintainer: This is a terminal state, meaning the |
6e4d98d
to
26e81d4
Compare
CLAs look good, thanks! |
@gkalpak PTAL |
I have checked that this code passes #14276 |
@IgorMinar or @mhevery can we get a LGTM on the public api file change? |
@@ -6,13 +6,14 @@ | |||
* found in the LICENSE file at https://angular.io/license | |||
*/ | |||
|
|||
import {CssSelector, SelectorMatcher, createElementCssSelector} from '@angular/compiler'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line will now be included in upgrade/static
. Can someone (@alexeagle?) verify that this won't have unwanted side effects (such as pulling in too much code from @angular/compiler
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry this is obsured from you :(
We could maybe split the modules/@angular/upgrade
tsconfig into two compilation units that match how we compile it internally.
The short answer is that we compile only these files
"modules/@angular/upgrade/src/common/**/*.ts",
"modules/@angular/upgrade/src/static/**/*.ts",
"modules/@angular/upgrade/src/facade/**/*.ts",
"modules/@angular/upgrade/static.ts",
so this file would need to be moved out of common, or needs to be excluded from the compilation (and then not imported by anything else in static)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(because of limitations in the treeshaker, we don't include @angular/compiler as a transitive dependency of angular apps at all)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexeagle shall I move these functions into some common place, @angular/common
(??) or maybe facade
? Or should i just make a copy of the files (I feel very bad about that) into upgrade
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like either 1) upgrade shouldn't use these because they are part of the compiler, or 2) they are not really part of the compiler and could move to common.
@tbosch or @IgorMinar ?
Please resolve conflicts |
Copy it is then. I will update the PR tomorrow. |
Unfortunately, @mhevery, I don't think that making a copy is an option. While these three imports look small on the surface, they hide loads of code in the form of the HTML template parser. |
@petebacondarwin ok, lets put in in the facade then. |
Actually looking at this again, I think we can accomplish what we want by copying the |
d087015
to
8c88cca
Compare
@@ -561,7 +561,7 @@ export class UpgradeAdapter { | |||
providers: [ | |||
{provide: $INJECTOR, useFactory: () => ng1Injector}, | |||
{provide: $COMPILE, useFactory: () => ng1Injector.get($COMPILE)}, | |||
{provide: ContentProjectionHelper, useClass: DynamicContentProjectionHelper}, | |||
{provide: NgContentSelectorHelper, useClass: DynamicNgContentSelectorHelper}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't we get rid of having to provide NgContentSelectorHelper
by automaticalky populating info.selector
in the dynamic version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean do it here? https://github.com/petebacondarwin/angular/blob/8c88cca5f54b6eca51dcea3d3350946fe744e8a0/modules/%40angular/upgrade/src/dynamic/upgrade_adapter.ts#L194
Yes that sounds reasonable. I'll try it out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly we cannot do that because the downgradeComponent
helper is called before we bootstrap, so the Compiler
service is not available.
I guess we could rewrite everything so that this information could be computed lazily after bootstrap but I don't think the benefit of removing the NgContentSelectorHelper
would warrant the effort and the churn.
8c88cca
to
dbb8b53
Compare
This PR needs to be rebased. |
dbb8b53
to
6d0e1f0
Compare
@chuckjaz - done. |
This PR looks like it needs to be rebased again. |
6d0e1f0
to
88eb58b
Compare
const ngContentIndices: number[] = []; | ||
const node = nodes[j]; | ||
const selector = | ||
createElementCssSelector(node.nodeName.toLowerCase(), getAttributesAsArray(node)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't we use element.matches
(see https://developer.mozilla.org/en-US/docs/Web/API/Element/matches)? Angular already verified during compiling the component that the selector is a "simple" selector that could be resolved via CssSelector
, and CssSelector
is a strict subset of the full css spec...
* ask the compiler for the selectors of a component. | ||
*/ | ||
export class NgContentSelectorHelper { | ||
getNgContentSelectors(info: ComponentInfo): string[] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should change ComponentFactory
to have a getter ngContentSelectors
. This way, we can use this information in AOT and JIT mode without the user specifying it...
* that appear in the downgraded component's template. | ||
* These selectors must be provided in the order that they appear in the template as they are | ||
* mapped by index to the projected nodes. | ||
* | ||
* @experimental | ||
*/ | ||
export function downgradeComponent(info: /* ComponentInfo */ { | ||
component: Type<any>; | ||
inputs?: string[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a string array here will break with closure enhanced optimizations. Also, I think we should change the compiler to provide an inputs
and outputs
map in the ComponentFactory
class, together with ngContentSelectors
. Something like this:
class ComponentFactory<T> {
// mapping from mangeled input name to non mangeled name.
inputs: {[key: string]: string};
// mapping from mangeled output name to non mangeled name.
outputs: {[key: string]: string};
// array of the selectors users in `ng-content`.
ngContentSelectors: string[];
}
Sorry, I missed this PR somehow... But I do think we should change this before cutting the next rc as
|
@tbosch: |
See #15156 for the cleanups... |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Closes #14261
Please check if the PR fulfills these requirements
What kind of change does this PR introduce? (check one with "x")
What is the current behavior? (You can also link to an open issue here)
downgradedComponents in upgrade/static did not correctly project multi-slot content.
What is the new behavior?
Does this PR introduce a breaking change? (check one with "x")
If this PR contains a breaking change, please describe the impact and migration path for existing applications: ...
Other information: