<commit_before>pageflow.CollectionView = Backbone.Marionette.View.extend({
  initialize: function() {
    this.rendered = false;
    this.itemViews = new Backbone.ChildViewContainer();

    this.collection.map(this.addItem, this);

    this.listenTo(this.collection, 'add', this.addItem);
    this.listenTo(this.collection, 'remove', this.removeItem);
    this.listenTo(this.collection, 'sort', this.sort);

    if (this.options.loadingViewConstructor) {
      this.listenTo(this.collection, 'request', function() {
        this.loading = true;
        this.togglePlaceHolder();
      });
      this.listenTo(this.collection, 'sync', function() {
        this.loading = false;
        this.togglePlaceHolder();
      });
    }
  },

  render: function() {
    if (!this.rendered) {
      this.$el.append(this.itemViews.map(function(itemView) {
        itemView.$el.data('view', itemView);
        return itemView.render().el;
      }));

      this.togglePlaceHolder();
      this.rendered = true;
    }

    return this;
  },

  onClose: function() {
    this.itemViews.call('close');

    this.closePlaceHolderView();
  },

  addItem: function(item) {
    var view = new this.options.itemViewConstructor(_.extend({
      model: item
    }, this.getItemViewOptions(item)));

    this.itemViews.add(view);

    if (this.rendered) {
      var index = this.collection.indexOf(item);

      view.render();
      view.$el.data('view', view);

      if (index > 0) {
        this.$el.children().eq(index - 1).after(view.el);
      }
      else {
        this.$el.prepend(view.el);
      }

      this.togglePlaceHolder();
    }
  },

  removeItem: function(item) {
    var view = this.itemViews.findByModel(item);

    if (view) {
      this.itemViews.remove(view);
      view.close();

      this.togglePlaceHolder();
    }
  },

  sort: function() {
    var last = null;

    this.collection.each(function(item) {
      var element = this.itemViews.findByModel(item).$el;

      if (last) {
        last.after(element);
      }
      else {
        this.$el.prepend(element);
      }

      last = element;
    }, this);
  },

  getItemViewOptions: function(item) {
    if (typeof this.options.itemViewOptions === 'function') {
      return this.options.itemViewOptions(item);
    }
    else {
      return this.options.itemViewOptions || {};
    }
  },

  closePlaceHolderView: function() {
    if (this.placeHolderView) {
      this.placeHolderView.close();
      this.placeHolderView = null;
    }
  },

  togglePlaceHolder: function() {<commit_msg>Make CollectionView sorting more robust<commit_after>pageflow.CollectionView = Backbone.Marionette.View.extend({
  initialize: function() {
    this.rendered = false;
    this.itemViews = new Backbone.ChildViewContainer();

    this.collection.map(this.addItem, this);

    this.listenTo(this.collection, 'add', this.addItem);
    this.listenTo(this.collection, 'remove', this.removeItem);
    this.listenTo(this.collection, 'sort', this.sort);

    if (this.options.loadingViewConstructor) {
      this.listenTo(this.collection, 'request', function() {
        this.loading = true;
        this.togglePlaceHolder();
      });
      this.listenTo(this.collection, 'sync', function() {
        this.loading = false;
        this.togglePlaceHolder();
      });
    }
  },

  render: function() {
    if (!this.rendered) {
      this.$el.append(this.itemViews.map(function(itemView) {
        itemView.$el.data('view', itemView);
        return itemView.render().el;
      }));

      this.togglePlaceHolder();
      this.rendered = true;
    }

    return this;
  },

  onClose: function() {
    this.itemViews.call('close');

    this.closePlaceHolderView();
  },

  addItem: function(item) {
    var view = new this.options.itemViewConstructor(_.extend({
      model: item
    }, this.getItemViewOptions(item)));

    this.itemViews.add(view);

    if (this.rendered) {
      var index = this.collection.indexOf(item);

      view.render();
      view.$el.data('view', view);

      if (index > 0) {
        this.$el.children().eq(index - 1).after(view.el);
      }
      else {
        this.$el.prepend(view.el);
      }

      this.togglePlaceHolder();
    }
  },

  removeItem: function(item) {
    var view = this.itemViews.findByModel(item);

    if (view) {
      this.itemViews.remove(view);
      view.close();

      this.togglePlaceHolder();
    }
  },

  sort: function() {
    var last = null;

    this.collection.each(function(item) {
      var itemView = this.itemViews.findByModel(item);
      var element;

      if (!itemView) {
        return;
      }

      element = itemView.$el;

      if (last) {
        last.after(element);
      }
      else {
        this.$el.prepend(element);
      }

      last = element;
    }, this);
  },

  getItemViewOptions: function(item) {
    if (typeof this.options.itemViewOptions === 'function') {
      return this.options.itemViewOptions(item);
    }
    else {
      return this.options.itemViewOptions || {};
    }
  },

  closePlaceHolderView: function() {
    if (this.placeHolderView) {
      this.placeHolderView.close();
      this.placeHolderView = null;
    }
  },

  togglePlaceHolder: function() {
{'fraction_non_alphanumeric': 0.1484958804368653, 'fraction_numerical': 0.0007664303506418854, 'mean_word_length': 2.5198921105866487, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '6269821', 'n_tokens_mistral': 1660, 'n_tokens_neox': 1599, 'n_words': 261}