<commit_before>define([
  'jquery',
  'nbd/util/construct',
  '../Component',
  '../Controller',
  '../trait/eventMappable'
], function($, construct, Component, Controller, eventMappable) {
  'use strict';

  /**
   * Manages a DOM region that contains a list of Controllers for each item
   * @constructor
   * @extends BeFF/Component
   * @module  Container
   */
  return Component.extend({
    /**
     * The controller class constructed for each item in the container
     * Defaults to the base BeFF/Controller unless overridden
     * @type {BeFF/Controller}
     */
    Controller: Controller,

    /**
     * @param {$} $view The "container" element that should be managed
     */
    init: function($view) {
      this.$view = $view;
    },

    bind: function() {
      this._mapEvents();
      this._nodes = this.$view.children().toArray()
      .map(this.decorate, this);
      return this;
    },

    unbind: function() {
      this._undelegateEvents();
      return this;
    },

    /**
     * Constructs an instance of the controller with the passed args
     * @return {BeFF/Controller} An instance of the controller
     */
    decorate: function() {
      var inst = construct.apply(this.Controller, arguments);
      if (inst.on) {
        this.listenTo(inst, 'destroy', function() {
          this.remove(inst);
        });
      }
      return inst;
    },

    /**
     * Constructs a controller for every element of the resultset
     * and renders the controller into the managed $view
     * @param {Array} resultset A list of JSON objects representing new items in the container
     * @returns {Array} A list of the newly constructed controllers rendered into $view
     */
    add: function(resultset) {
      if (!resultset || !Array.isArray(resultset)) { return; }
      var nodes = resultset.map(this.decorate, this).filter(Boolean);

      nodes.forEach(function(node) {
        return node.render && node.render(this.$view);
      }, this);

      this._nodes = this._nodes.concat(nodes);

      return nodes;
    },

    remove: function(node) {
      var i;
      if (~(i = this._nodes.indexOf(node))) {
        this._nodes.splice(i, 1);
      }
    },

    /**
     * Destroys all of the managed controllers and empties
     * the managed $view
     * @return {$} The newly emptied $view
     */
    empty: function() {
      if (!this._nodes) {
        return this.$view;
      }
      this._nodes.forEach(function(item) {
        return item && item.destroy && item.destroy();
      });
      this._nodes.length = 0;
      return this.$view.empty();
    },

    /**
     * @return {Boolean} Whether or not there are any managed controllers
     */
    isEmpty: function() {
      return !this._nodes || !this._nodes.length;
    },<commit_msg>Component: Triggers update event on _nodes add/remove manipulation. Fixes #23<commit_after>define([
  'jquery',
  'nbd/util/construct',
  '../Component',
  '../Controller',
  '../trait/eventMappable'
], function($, construct, Component, Controller, eventMappable) {
  'use strict';

  /**
   * Manages a DOM region that contains a list of Controllers for each item
   * @constructor
   * @extends BeFF/Component
   * @module  BeFF/Component/Container
   */
  return Component.extend({
    /**
     * The controller class constructed for each item in the container
     * Defaults to the base BeFF/Controller unless overridden
     * @type {BeFF/Controller}
     */
    Controller: Controller,

    /**
     * @param {$} $view The "container" element that should be managed
     */
    init: function($view) {
      this.$view = $view;
    },

    /**
     * @fires module:BeFF/Component/Container#postBind
     * @return {BeFF/Component/Container}
     */
    bind: function() {
      this._mapEvents();
      this._nodes = this.$view.children().toArray()
      .map(this.decorate, this);

      this.trigger('postBind');
      return this;
    },

    unbind: function() {
      this._undelegateEvents();
      return this;
    },

    /**
     * Constructs an instance of the controller with the passed args
     * @return {BeFF/Controller} An instance of the controller
     */
    decorate: function() {
      var inst = construct.apply(this.Controller, arguments);
      if (inst.on) {
        this.listenTo(inst, 'destroy', function() {
          this.remove(inst);
        });
      }
      return inst;
    },

    /**
     * Constructs a controller for every element of the resultset
     * and renders the controller into the managed $view
     * @param {Array} resultset A list of JSON objects representing new items in the container
     * @fires module:BeFF/Component/Container#add
     * @returns {Array} A list of the newly constructed controllers rendered into $view
     */
    add: function(resultset) {
      if (!resultset || !Array.isArray(resultset)) { return; }
      var nodes = resultset.map(this.decorate, this).filter(Boolean);

      nodes.forEach(function(node) {
        this.trigger('add', node);
        return node.render && node.render(this.$view);
      }, this);

      this._nodes = this._nodes.concat(nodes);

      return nodes;
    },

    /**
     * @fires module:BeFF/Component/Container#removed
     */
    remove: function(node) {
      var i;
      if (~(i = this._nodes.indexOf(node))) {
        this._nodes.splice(i, 1);
        this.trigger('removed');
      }
    },

    /**
     * Destroys all of the managed controllers and empties
     * the managed $view
     * @return {$} The newly emptied $view
     */
    empty: function() {
      if (!this._nodes) {
        return this.$view;
      }
      this._nodes.forEach(function(item) {
        return item && item.destroy && item.destroy();
      });
      this._nodes.length = 0;
      return this.$view.empty();
    },

    /**
     * @return {Boolean} Whether or not there are any managed controllers
     */
    isEmpty: function() {
      return !this._nodes || !this._nodes.length;
    },
{'fraction_non_alphanumeric': 0.13028934604448905, 'fraction_numerical': 0.0010035122930255895, 'mean_word_length': 2.359550561797753, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2604406', 'n_tokens_mistral': 1737, 'n_tokens_neox': 1701, 'n_words': 479}