<commit_before>// Backbone.Component
// ==================
// 
// A thin layer on top of Backbone's view class to add nested child views.
//
// ---

Backbone.Component = Backbone.View.extend({

  // Override constructor so Components can use initialise normally.
  constructor: function() {
    this._setup();
    Backbone.View.apply(this, arguments);
  },

  // Public API
  // ----------
  // ----------

  // Add a child view to the end of the element.
  // Optionally specify a selector within the view to attach to.
  // Aliased to `add`.
  append: function(view, selector) {
    this._addChild(view, selector, 'append');
    return this;
  },

  // Add a child view to the beginning of the view's element.
  // Optionally specify a selector within the view to attach to.
  prepend: function(view, selector) {
    this._addChild(view, selector, 'prepend');
    return this;
  },

  // Private methods
  // ----------
  // ----------

  // Initial setup. Create new child array, alias add to append, and wrap
  // render and remove methods.
  _setup: function() {
    this._children = [];
    this.add = this.append;
    this.render = this._wrapRender();
    this.remove = this._wrapRemove();
  },

  // Add a child view to an internal array, keeping a reference to
  // the element and attach method it should use.
  _addChild: function(view, selector, method) {
    var child = { view: view, selector: selector, method: method };

    // Assign a method to the child so it can remove itself from
    // `_children` array when it's removed.
    var removeFromParent = _.bind(this._removeFromParent, this);
    view._removeFromParent = _.partial(removeFromParent, child);

    this._children.push(child);
  },

  // Call remove for each child added to the view.
  _removeChildren: function() {
    _.invoke(_.pluck(this._children, 'view'), 'remove');
  },

  _removeFromParent: function(child) {
    this._children = _.without(this._children, child);
  },

  // Wrap render to automatically attach all children.
  _wrapRender: function() {
    var wrapper = function(render) {
      var args = Array.prototype.slice.call(arguments, 1);
      render.apply(this, args);
      this._attachChildren();
      return this;
    };

    var originalRender = _.bind(this.render, this);
    return _.wrap(originalRender, wrapper);
  },

  // Wrap remove to automatically remove all children and itself from 
  // its parent.
  _wrapRemove: function() {
    var wrapper = function(remove) {
      this._removeFromParent();
      this._removeChildren();
      remove();
      return this;
    };

    var originalRemove = _.bind(this.remove, this);
    return _.wrap(originalRemove, wrapper);
  },

  // Attach child to the correct element and with correct method.
  // Defaults to `this.$el` and `append`.
  _attachChild: function(child) {
    var method = child.method || 'append';
    var target = child.selector ? this.$(child.selector) : this.$el;

    child.view.render();
    target[method](child.view.$el);
  },

  // Attach all children in the right order.
  // Call `delegateEvents` for each child view so handlers are correctly
  // bound after being attached.
  _attachChildren: function() {
    _.each(this._children, function(child) {
      this._attachChild(child);<commit_msg>pass args to remove call<commit_after>// Backbone.Component
// ==================
// 
// A thin layer on top of Backbone's view class to add nested child views.
//
// ---

Backbone.Component = Backbone.View.extend({

  // Override constructor so Components can use initialise normally.
  constructor: function() {
    this._setup();
    Backbone.View.apply(this, arguments);
  },

  // Public API
  // ----------
  // ----------

  // Add a child view to the end of the element.
  // Optionally specify a selector within the view to attach to.
  // Aliased to `add`.
  append: function(view, selector) {
    this._addChild(view, selector, 'append');
    return this;
  },

  // Add a child view to the beginning of the view's element.
  // Optionally specify a selector within the view to attach to.
  prepend: function(view, selector) {
    this._addChild(view, selector, 'prepend');
    return this;
  },

  // Private methods
  // ----------
  // ----------

  // Initial setup. Create new child array, alias add to append, and wrap
  // render and remove methods.
  _setup: function() {
    this._children = [];
    this.add = this.append;
    this.render = this._wrapRender();
    this.remove = this._wrapRemove();
  },

  // Add a child view to an internal array, keeping a reference to
  // the element and attach method it should use.
  _addChild: function(view, selector, method) {
    var child = { view: view, selector: selector, method: method };

    // Assign a method to the child so it can remove itself from
    // `_children` array when it's removed.
    var removeFromParent = _.bind(this._removeFromParent, this);
    view._removeFromParent = _.partial(removeFromParent, child);

    this._children.push(child);
  },

  // Call remove for each child added to the view.
  _removeChildren: function() {
    _.invoke(_.pluck(this._children, 'view'), 'remove');
  },

  _removeFromParent: function(child) {
    this._children = _.without(this._children, child);
  },

  // Wrap render to automatically attach all children.
  _wrapRender: function() {
    var wrapper = function(render) {
      var args = Array.prototype.slice.call(arguments, 1);
      render.apply(this, args);
      this._attachChildren();
      return this;
    };

    var originalRender = _.bind(this.render, this);
    return _.wrap(originalRender, wrapper);
  },

  // Wrap remove to automatically remove all children and itself from 
  // its parent.
  _wrapRemove: function() {
    var wrapper = function(remove) {
      this._removeFromParent();
      this._removeChildren();

      var args = Array.prototype.slice.call(arguments, 1);
      remove.apply(this, args);
      return this;
    };

    var originalRemove = _.bind(this.remove, this);
    return _.wrap(originalRemove, wrapper);
  },

  // Attach child to the correct element and with correct method.
  // Defaults to `this.$el` and `append`.
  _attachChild: function(child) {
    var method = child.method || 'append';
    var target = child.selector ? this.$(child.selector) : this.$el;

    child.view.render();
    target[method](child.view.$el);
  },

  // Attach all children in the right order.
  // Call `delegateEvents` for each child view so handlers are correctly
  // bound after being attached.
  _attachChildren: function() {
    _.each(this._children, function(child) {
      this._attachChild(child);
{'fraction_non_alphanumeric': 0.13643876784372652, 'fraction_numerical': 0.00045078888054094667, 'mean_word_length': 2.8034285714285714, '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': '1639746', 'n_tokens_mistral': 1910, 'n_tokens_neox': 1857, 'n_words': 622}