Skip to content
This repository has been archived by the owner on Apr 4, 2019. It is now read-only.

Properly visit MorphLists in visitChildren. #407

Merged
merged 1 commit into from
Sep 2, 2015

Conversation

rwjblue
Copy link
Collaborator

@rwjblue rwjblue commented Sep 2, 2015

visitChildren is used internally to visit all Morph's and call a callback on each one found. The most common usage of visitChildren in HTMLBars itself is for clearing morphs before rendering a new template.

Prior to this change, if we encounter a node with morphList we:

  • add the morphList to the list of nodes to traverse
  • call the provided callback
  • traverse the MorphList and add all morphs found there to the list of
    morphs to call the callback on

In general that is fine, except when the callback itself (in step 2 above) is mutating the morph and preventing the MorphList from being traversed. This is the case when changing an {{if}} with a {{each}} from the template to the inverse block, in that case the callback is calling MorphList#clear() which nullifies the MorphList but does not call the various hooks (didDestroyNode specifically) so any morphs would be leaked.

This change tweaks visitChildren to unroll a MorphList upon encountering it (instead of waiting util after the callback has been called on it). The included test demonstrates the memory leak that was occurring in Ember and that it is properly fixed.

`visitChildren` is used internally to visit all `Morph`'s and call a
callback on each one found.  The most common usage of `visitChildren` in
HTMLBars itself is for clearing morphs before rendering a new template.

Prior to this change, if we encounter a node with `morphList` we:

* add the `morphList` to the list of nodes to traverse
* call the provided callback
* traverse the `MorphList` and add all morphs found there to the list of
  morphs to call the callback on

In general that is fine, except when the callback itself (in step 2
above) is mutating the `morph` and preventing the `MorphList` from being
traversed. This is the case when changing an `{{if}}` with a `{{each}}`
from the template to the inverse block, in that case the callback is
calling `MorphList#clear()` which nullifies the `MorphList` but does not
call the various hooks (`didDestroyNode` specifically) so any morphs
would be leaked.

This change tweaks `visitChildren` to unroll a `MorphList` upon
encountering it (instead of waiting util after the callback has been
called on it). The included test demonstrates the memory leak that was
occurring in Ember and that it is properly fixed.
@rwjblue
Copy link
Collaborator Author

rwjblue commented Sep 2, 2015

r+ from @mmun in chat

rwjblue added a commit that referenced this pull request Sep 2, 2015
Properly visit MorphLists in visitChildren.
@rwjblue rwjblue merged commit 1f1aa2e into tildeio:master Sep 2, 2015
@rwjblue rwjblue deleted the properly-visit-morph-lists branch September 2, 2015 03:41
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant