docs/vendor.js
function destroyViewTree(rootView) {
    // If the view has no children, we can clean it up and return early.
    if (rootView[TVIEW].childIndex === -1) {
        return cleanUpView(rootView);
    }
    var viewOrContainer = getLViewChild(rootView);
    while (viewOrContainer) {
        var next = null;
        if (viewOrContainer.length >= HEADER_OFFSET) {
            // If LViewData, traverse down to child.
            var view = viewOrContainer;
            if (view[TVIEW].childIndex > -1)
                next = getLViewChild(view);
        }
        else {
            // If container, traverse down to its first LViewData.
            var container = viewOrContainer;
            if (container[VIEWS].length)
                next = container[VIEWS][0].data;
        }
        if (next == null) {
            // Only clean up view when moving to the side or up, as destroy hooks
            // should be called in order from the bottom up.
            while (viewOrContainer && !viewOrContainer[NEXT] && viewOrContainer !== rootView) {
                cleanUpView(viewOrContainer);
                viewOrContainer = getParentState(viewOrContainer, rootView);
            }
            cleanUpView(viewOrContainer || rootView);
            next = viewOrContainer && viewOrContainer[NEXT];
        }
        viewOrContainer = next;
    }
}
function destroyViewTree(rootView) {
    // If the view has no children, we can clean it up and return early.
    if (rootView[TVIEW].childIndex === -1) {
        return cleanUpView(rootView);
    }
    var viewOrContainer = getLViewChild(rootView);
    while (viewOrContainer) {
        var next = null;
        if (viewOrContainer.length >= HEADER_OFFSET) {
            // If LViewData, traverse down to child.
            var view = viewOrContainer;
            if (view[TVIEW].childIndex > -1)
                next = getLViewChild(view);
        }
        else {
            // If container, traverse down to its first LViewData.
            var container = viewOrContainer;
            if (container[VIEWS].length)
                next = container[VIEWS][0].data;
        }
        if (next == null) {
            // Only clean up view when moving to the side or up, as destroy hooks
            // should be called in order from the bottom up.
            while (viewOrContainer && !viewOrContainer[NEXT] && viewOrContainer !== rootView) {
                cleanUpView(viewOrContainer);
                viewOrContainer = getParentState(viewOrContainer, rootView);
            }
            cleanUpView(viewOrContainer || rootView);
            next = viewOrContainer && viewOrContainer[NEXT];
        }
        viewOrContainer = next;
    }
}
function destroyViewTree ( rootView ) { // If the view has no children, we can clean it up and return early. if ( rootView [ TVIEW ] . childIndex === - 1 ) { return cleanUpView ( rootView ) ; } var viewOrContainer = getLViewChild ( rootView ) ; while ( viewOrContainer ) { var next = null ; if ( viewOrContainer . length >= HEADER_OFFSET ) { // If LViewData, traverse down to child. var view = viewOrContainer ; if ( view [ TVIEW ] . childIndex > - 1 ) next = getLViewChild ( view ) ; } else { // If container, traverse down to its first LViewData. var container = viewOrContainer ; if ( container [ VIEWS ] . length ) next = container [ VIEWS ] [ 0 ] . data ; } if ( next == null ) { // Only clean up view when moving to the side or up, as destroy hooks // should be called in order from the bottom up. while ( viewOrContainer && ! viewOrContainer [ NEXT ] && viewOrContainer !== rootView ) { cleanUpView ( viewOrContainer ) ; viewOrContainer = getParentState ( viewOrContainer , rootView ) ; } cleanUpView ( viewOrContainer || rootView ) ; next = viewOrContainer && viewOrContainer [ NEXT ] ; } viewOrContainer = next ; } }
Traverses down and up the tree of views and containers to remove listeners and
call onDestroy callbacks.

Notes:
- Because it's used for onDestroy calls, it needs to be bottom-up.
- Must process containers instead of their views to avoid splicing
when views are destroyed and re-added.
- Using a while loop because it's faster than recursion
- Destroy only called on movement to sibling or movement to parent (laterally or up)

@param rootView The view to destroy
Traverses down and up the tree of views and containers to remove listeners and call onDestroy callbacks .