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: remove child from old parent when moving to new parent via addChild #5702

Merged
merged 2 commits into from Jan 8, 2019

Conversation

Projects
None yet
3 participants
@dustin71728
Copy link
Contributor

dustin71728 commented Dec 20, 2018

Description

A child component may have been assigned to another
parent before assigning that child component to the
new parent via "addChild" method. In this case, the
original parent should remove the child then it can
be safely added back to the new parent. This commit
will keep the parent's "children_" and its DOM
element's child nodes in the consistent state.

Specific Changes proposed

Remove the specific child component from the old parent component before adding the child component to the new parent

Requirements Checklist

  • Feature implemented / Bug fixed
  • If necessary, more likely in a feature request than a bug fix
    • Change has been verified in an actual browser (Chome, Firefox, IE)
    • Unit Tests updated or fixed
    • Docs/guides updated
    • Example created (starter template on JSBin)
  • Reviewed by Two Core Contributors
@welcome

This comment has been minimized.

Copy link

welcome bot commented Dec 20, 2018

💖 Thanks for opening this pull request! 💖

Things that will help get your PR across the finish line:

  • Run npm run lint -- --errors locally to catch formatting errors earlier.
  • Include tests when adding/changing behavior.
  • Include screenshots and animated GIFs whenever possible.

We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.

fix: remove child from old parent when moving to new parent via addChild
A child component may have been assigned to another
parent before assigning that child component to the
new parent via "addChild" method. In this case, the
original parent should remove the child then it can
be safely added back to the new parent. This commit
will keep the parent's "children_" and its DOM
element's child nodes in the consistent state.

@dustin71728 dustin71728 force-pushed the dustin71728:fix/component-addchild branch from 506edec to d822ed3 Dec 20, 2018

@dustin71728 dustin71728 changed the title fix: remove child from old parent when moving to new parent via addCh… fix: remove child from old parent when moving to new parent via addChild Dec 20, 2018

@gkatsev

This comment has been minimized.

Copy link
Member

gkatsev commented Dec 20, 2018

So, the reason for this is so that the internal children array in our component system stays up-to-date when components move around in the DOM? Otherwise, the previous parent would have a reference to the child component even if the child component wasn't actually a child anymore?
Would you be able to add a test for this?

@dustin71728

This comment has been minimized.

Copy link
Contributor Author

dustin71728 commented Dec 21, 2018

So, the reason for this is so that the internal children array in our component system stays up-to-date when components move around in the DOM? Otherwise, the previous parent would have a reference to the child component even if the child component wasn't actually a child anymore?
Would you be able to add a test for this?

Yes, for example, if I want to add the new menu item of the menu button dynamically, a class can be implemented as follows:

export class MutableMenuButton extends MenuButton {
  constructor(player, options) {
    super(player, options)

    this.items_ = []
  }

  insertItem(item, index) {
    this.items_.splice(index, 0, item)

    // Trigger the `update` method from `MenuButton` to re-render the layout
    this.update()
  }

  // Override the abstract method
  createItems() {
    return this.items_
  }
}

export default MutableMenuButton

But what i found is whenever the "MutableMenuButton".inserItem gets called, the existed menu item is removed from the new menu that belongs to the menu button.
After digging into the code, I found that the old, about to be removed menu instance still hold the child component that is already to move to the new menu component.
Because any discarded component will dispose of its children, so the DOM element of the existed menu item attached to the new menu will be erased from the DOM, this is why the new menu can't see the menu item that already in place.

So that is why I commit this change, if you think that is acceptable, I will add some tests.

@dustin71728

This comment has been minimized.

Copy link
Contributor Author

dustin71728 commented Dec 24, 2018

I have added two unit test cases for this fix.
If the fix commit is reverted, these tests will fail due to the reason I mentioned before.

@gkatsev

gkatsev approved these changes Jan 3, 2019

Copy link
Member

gkatsev left a comment

Awesome, thanks for the tests! I was able to verify locally that tests fail and the change makes sense. With me approving, we just need someone else from the core team to approve for it to land.

@gkatsev gkatsev added this to the 7.4.x milestone Jan 3, 2019

@dustin71728

This comment has been minimized.

Copy link
Contributor Author

dustin71728 commented Jan 4, 2019

It is my pleasure. 😄

@misteroneill
Copy link
Member

misteroneill left a comment

Nice!

@gkatsev gkatsev merged commit dd63cf9 into videojs:master Jan 8, 2019

2 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
netlify/videojs-docs/deploy-preview Deploy preview ready!
Details
@welcome

This comment has been minimized.

Copy link

welcome bot commented Jan 8, 2019

Congrats on merging your first pull request! 🎉🎉🎉

gkatsev added a commit that referenced this pull request Jan 8, 2019

fix: remove child from old parent when moving to new parent via addCh…
…ild (#5702)

A child component may have been assigned to another
parent before assigning that child component to the
new parent via "addChild" method. In this case, the
original parent should remove the child then it can
be safely added back to the new parent. This commit
will keep the parent's "children_" and its DOM
element's child nodes in the consistent state.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment