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

fix(ivy): remove DOM nodes from their real parent vs saved parent #28455

Closed
wants to merge 2 commits into from

Conversation

jelbourn
Copy link
Member

Currently, DOM node removal called removeChild on the saved parent
node when destroying a component. However, this will fail if the
component has been manually moved in the DOM. This change makes the
removal always use the node's real parentNode and ignore the provided
parent.

Reference: FW-977

@jelbourn jelbourn added hotlist: components team Related to Angular CDK or Angular Material area: core Issues related to the framework runtime target: major This PR is targeted for the next major release comp: ivy labels Jan 30, 2019
@jelbourn jelbourn requested a review from a team as a code owner January 30, 2019 18:26
@ngbot ngbot bot added this to the needsTriage milestone Jan 30, 2019
@jelbourn jelbourn added the action: review The PR is still awaiting reviews from at least one requested reviewer label Jan 30, 2019
packages/core/src/render3/node_manipulation.ts Outdated Show resolved Hide resolved
packages/core/test/render3/view_container_ref_spec.ts Outdated Show resolved Hide resolved
@@ -598,8 +598,16 @@ function nativeAppendOrInsertBefore(
*/
export function nativeRemoveChild(
renderer: Renderer3, parent: RElement, child: RNode, isHostElement?: boolean): void {
isProceduralRenderer(renderer) ? renderer.removeChild(parent as RElement, child, isHostElement) :
parent.removeChild(child);
if (isProceduralRenderer(renderer)) {

Choose a reason for hiding this comment

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

If we do this logic here in nativeRemoveChild it will mean that we still execute all the logic to find a logical render parent and this is useless. I would rather modify the removeChild function and there lookup a parent from the DOM, instead of executing const parentNative = getRenderParent(childTNode, currentView);

Then the null check be in there as well and you wouldn't need to modify renderer

Copy link
Member Author

Choose a reason for hiding this comment

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

This is what I originally had and @kara asked to change it. @kara what are your thoughts here?

Copy link
Contributor

@kara kara Feb 1, 2019

Choose a reason for hiding this comment

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

@jelbourn I believe @pkozlowski-opensource is actually talking about Ivy's version of removeChild here (not the renderer):
https://github.com/angular/angular/blob/master/packages/core/src/render3/node_manipulation.ts#L696

I'd agree with him that we should update that function to remove the logic that searches the tree for the render parent manually.

Copy link
Member Author

Choose a reason for hiding this comment

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

I totally misread Pawel's original comment; I hadn't seen that getRenderParent function earlier.

In making the change to avoid calling that, I didn't want to move the "get parent node" bit into removeChild because then nativeRemoveChild would have the assumption that it's the right parent node baked into it. So, I instead changed removeChild to removeNode and made it just a pass-through to nativeRemoveChild, which also now does not have parent in its arguments.

Let me know what you think.

Copy link
Member

@pkozlowski-opensource pkozlowski-opensource left a comment

Choose a reason for hiding this comment

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

I think that we should rather:

  • modify the removeChild function (see my in-line comments);
  • have a TestBed test on top of / instead of renderer3 runtime test

Happy to help if needed but I would like to very much avoid the situation where we do both logical render parent lookup and lookup in the DOM.

@mhevery mhevery self-assigned this Jan 31, 2019
@kara kara unassigned mhevery Feb 1, 2019
@kara kara added action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Feb 1, 2019
@jelbourn jelbourn requested a review from a team as a code owner February 1, 2019 23:39
Copy link
Member Author

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

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

Comments addressed, let me know what you think

@@ -598,8 +598,16 @@ function nativeAppendOrInsertBefore(
*/
export function nativeRemoveChild(
renderer: Renderer3, parent: RElement, child: RNode, isHostElement?: boolean): void {
isProceduralRenderer(renderer) ? renderer.removeChild(parent as RElement, child, isHostElement) :
parent.removeChild(child);
if (isProceduralRenderer(renderer)) {
Copy link
Member Author

Choose a reason for hiding this comment

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

I totally misread Pawel's original comment; I hadn't seen that getRenderParent function earlier.

In making the change to avoid calling that, I didn't want to move the "get parent node" bit into removeChild because then nativeRemoveChild would have the assumption that it's the right parent node baked into it. So, I instead changed removeChild to removeNode and made it just a pass-through to nativeRemoveChild, which also now does not have parent in its arguments.

Let me know what you think.

@jelbourn jelbourn force-pushed the dom-moved-removal branch 3 times, most recently from 02eba52 to b57c765 Compare February 2, 2019 00:25
renderer.removeChild(renderParent, child, isHostElement);
}
} else {
// We intentionally don't use the given parent node since it may no longer
Copy link
Contributor

Choose a reason for hiding this comment

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

There is no given parent node anymore, right?

Copy link
Member

Choose a reason for hiding this comment

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

So the idea behind the native[...]() functions in this file that those are here to basically abstract a renderer type being used. So far those functions didn't have any logic and I would love to keep it this way.

I would rather prefer that we keep nativeRemoveChild "dumb" and move all the "logic" into the removeChild function. I find this approach easier to follow and IMO the code is shorter / simpler (less checks / branching logic).

I've pushed a fixup commit I've pushed a fixup commit a529638 to your branch with the changes I'm describing above, please review. to your branch with the changes I'm describing above, please review.

if (parentNative) {
nativeRemoveChild(currentView[RENDERER], parentNative, childEl);
}
export function removeNode(childTNode: TNode, childEl: RNode, currentView: LView): void {

Choose a reason for hiding this comment

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

childTNode argument is not used here any more, remove

Copy link
Member

Choose a reason for hiding this comment

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

Actually, I've pushed a fixup commit a529638 to your branch with the changes I'm describing above, please review.

@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 or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok 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 all the commit author(s), set the cla label to yes (if enabled on your project), and then merge this pull request when appropriate.

@googlebot googlebot removed the cla: yes label Feb 4, 2019
Copy link
Member

@pkozlowski-opensource pkozlowski-opensource left a comment

Choose a reason for hiding this comment

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

LGTM with the fixup commit but we can iterate more if @jelbourn has objections

@pkozlowski-opensource
Copy link
Member

@jelbourn I've pushed a fixup commit and approved the PR with it. Feel free to apply the merge label if this looks good to you or ask / push changes if you want us to iterate more.

@kara kara added cla: yes and removed action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews cla: no labels Feb 4, 2019
@googlebot
Copy link

A Googler has manually verified that the CLAs look good.

(Googler, please make sure the reason for overriding the CLA status is clearly documented in these comments.)

@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 or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok 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 all the commit author(s), set the cla label to yes (if enabled on your project), and then merge this pull request when appropriate.

@googlebot
Copy link

A Googler has manually verified that the CLAs look good.

(Googler, please make sure the reason for overriding the CLA status is clearly documented in these comments.)

@jelbourn jelbourn added the action: merge The PR is ready for merge by the caretaker label Feb 5, 2019
@jelbourn
Copy link
Member Author

jelbourn commented Feb 5, 2019

I'm good with the proposed changes

jelbourn and others added 2 commits February 5, 2019 11:53
Currently, DOM node removal called `removeChild` on the saved parent
node when destroying a component. However, this will fail if the
component has been manually moved in the DOM. This change makes the
removal always use the node's real `parentNode` and ignore the provided
`parent`.
@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 or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok 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 all the commit author(s), set the cla label to yes (if enabled on your project), and then merge this pull request when appropriate.

@googlebot
Copy link

A Googler has manually verified that the CLAs look good.

(Googler, please make sure the reason for overriding the CLA status is clearly documented in these comments.)

@matsko
Copy link
Contributor

matsko commented Feb 5, 2019

@matsko matsko closed this in 89eac70 Feb 6, 2019
@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 14, 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 area: core Issues related to the framework runtime cla: yes hotlist: components team Related to Angular CDK or Angular Material target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants