Skip to content
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

Merged
merged 1 commit into from
Mar 14, 2017

Conversation

petebacondarwin
Copy link
Member

Closes #14261

Please check if the PR fulfills these requirements

What kind of change does this PR introduce? (check one with "x")

[x] Bugfix
[x] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Other... Please describe:

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")

[ ] Yes
[x] No

If this PR contains a breaking change, please describe the impact and migration path for existing applications: ...

Other information:

@petebacondarwin petebacondarwin added comp: upgrade/static freq2: medium action: review The PR is still awaiting reviews from at least one requested reviewer type: bug/fix feature Issue that requests a new feature labels Feb 3, 2017
*
* 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.
Copy link
Member

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 @@
/**
Copy link
Member

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,
Copy link
Member

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or not enough mocking!

@googlebot
Copy link

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 cla/google commit status will not change from this state. It's up to you to confirm consent of the commit author(s) and merge this pull request when appropriate.

@googlebot
Copy link

CLAs look good, thanks!

@googlebot googlebot added cla: yes and removed cla: no labels Feb 3, 2017
@petebacondarwin
Copy link
Member Author

@gkalpak PTAL

@petebacondarwin
Copy link
Member Author

I have checked that this code passes #14276

@petebacondarwin petebacondarwin added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Feb 9, 2017
@petebacondarwin
Copy link
Member Author

@IgorMinar or @mhevery can we get a LGTM on the public api file change?

@petebacondarwin petebacondarwin added action: review The PR is still awaiting reviews from at least one requested reviewer and removed action: merge The PR is ready for merge by the caretaker labels Feb 9, 2017
@@ -6,13 +6,14 @@
* found in the LICENSE file at https://angular.io/license
*/

import {CssSelector, SelectorMatcher, createElementCssSelector} from '@angular/compiler';
Copy link
Member

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)?

Copy link
Contributor

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)

Copy link
Contributor

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)

Copy link
Member Author

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?

Copy link
Contributor

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 ?

@mhevery
Copy link
Contributor

mhevery commented Feb 9, 2017

Please resolve conflicts

@petebacondarwin
Copy link
Member Author

Copy it is then. I will update the PR tomorrow.

@petebacondarwin
Copy link
Member Author

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.

@mhevery
Copy link
Contributor

mhevery commented Feb 10, 2017

@petebacondarwin ok, lets put in in the facade then.

@petebacondarwin
Copy link
Member Author

petebacondarwin commented Feb 28, 2017

Actually looking at this again, I think we can accomplish what we want by copying the selector.ts file and two files from the ml_parser folder; and then copying over a couple of functions from the template_parser.

@petebacondarwin petebacondarwin force-pushed the upgrade-static-projection branch 2 times, most recently from d087015 to 8c88cca Compare February 28, 2017 14:02
@@ -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},
Copy link
Member

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

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.

@petebacondarwin petebacondarwin added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Mar 8, 2017
@chuckjaz
Copy link
Contributor

This PR needs to be rebased.

@petebacondarwin
Copy link
Member Author

@chuckjaz - done.

@chuckjaz
Copy link
Contributor

This PR looks like it needs to be rebased again.

@chuckjaz chuckjaz merged commit 914797a into angular:master Mar 14, 2017
const ngContentIndices: number[] = [];
const node = nodes[j];
const selector =
createElementCssSelector(node.nodeName.toLowerCase(), getAttributesAsArray(node));
Copy link
Contributor

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[] {
Copy link
Contributor

@tbosch tbosch Mar 14, 2017

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[];
Copy link
Contributor

@tbosch tbosch Mar 14, 2017

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[];
}

@tbosch
Copy link
Contributor

tbosch commented Mar 14, 2017

Sorry, I missed this PR somehow... But I do think we should change this before cutting the next rc as

  • we probably want to deprecate the old way of specifying inputs and outputs as they break closure compiler.
  • we don't want users to repeat the selectors of ng-content (nor the inputs or outputs)
  • I would like to keep the CssSelector and parser classes private to the compiler, so that we can change it more easily...

@petebacondarwin
Copy link
Member Author

@tbosch:
Removing boilerplate from the upgrade/static API would make my day :-)
What do we need to do to make the compiler changes happen?
When we deprecate the inputs/outputs then they would just have no effect, right? Since the JIT/AOT compilers will do the work going forward.

@tbosch
Copy link
Contributor

tbosch commented Mar 14, 2017

See #15156 for the cleanups...

@petebacondarwin petebacondarwin deleted the upgrade-static-projection branch March 15, 2017 07:46
SamVerschueren pushed a commit to SamVerschueren/angular that referenced this pull request Mar 18, 2017
asnowwolf pushed a commit to asnowwolf/angular that referenced this pull request Aug 11, 2017
juleskremer pushed a commit to juleskremer/angular that referenced this pull request Aug 28, 2017
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 11, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes feature Issue that requests a new feature freq2: medium type: bug/fix
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[upgrade/static] Support targeted projection
7 participants