JSFiddle - React, Tailwind, and code Playground

by krisselden

HTML

<script src="http://cloud.github.com/downloads/emberjs/ember.js/ember-0.9.2.js"></script>
<script type="text/x-handlebars" data-template-name="hello">
<b>{{App.hello}}</b>
</script>
<button id="view-create">Create View</button>
<button id="view-destroy" style="display:none">Destroy View</button>
<button id="show-leak">Show Leak</button>
<button id="clear-chainWatchers">Clear chainWatchers</button>
<div id="app-root"></div>

JavaScript

var viewCreate$, viewDestroy$;

window.App = Em.Application.create({
    rootElement: '#app-root',
    hello: 'Hello World!'
});

function showLeak() {
    var appMeta = Em.meta(App),
        count = 0,
        helloChainWatchers, prop, helloNode, appNode, viewNode, view;
    if (appMeta.chainWatchers && (helloChainWatchers = appMeta.chainWatchers.hello)) {
        for (prop in helloChainWatchers) {
            if (helloChainWatchers.hasOwnProperty(prop)) {
                helloNode = helloChainWatchers[prop];
                appNode = helloNode._parent;
                viewNode = appNode._parent;
                view = viewNode._value;
                if (view.isDestroyed) {
                    count++;
                }
            }
        }
    }
    alert('App.hello binding holding onto ' + count + ' destroyed views');
}

function clearWatchers() {
    var appMeta = Em.meta(App);
    if (appMeta.chainWatchers) {
        delete appMeta.chainWatchers;
    }
}

$('#show-leak').click(showLeak);
$('#clear-chainWatchers').click(clearWatchers);

App.HelloView = Em.View.extend({
    templateName: 'hello',
    destroy: function () {
        var watchedEvents = Em.watchedEvents(this),
            i, j, listeners, target, method;
        for (i=0; i<watchedEvents.length; i++) {
            listeners = Em.listenersFor(watchedEvents[i]);
            for (j=0; j<listeners.length; j++) {
                target = listeners[i][0];
                method = listeners[i][1];
            }
        }
        return this._super.apply(this, arguments);
    }
});

function overwriteCachedTuple() {
    Em.normalizeTuple(window, 'Em.A');
}

function createView() {
    App.helloView = App.HelloView.create();
    App.helloView.appendTo('#app-root');
}

function destroyView() {
    if (App.helloView) {
        App.helloView.destroy();
        delete App.helloView;
        overwriteCachedTuple();
    }
}

viewCreate$ = $('#view-create');
viewDestroy$ =...