Code coverage report for src/backbone.picky.js

Statements: 94.74% (72 / 76)      Branches: 88.89% (32 / 36)      Functions: 94.12% (16 / 17)      Lines: 95.45% (63 / 66)     

All files » src/ » backbone.picky.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 1821 1                 1 24     1         41   27   27 27 27           41   17 17   12 12 12                     1 67 67     1           128   108 108 108             43   35 35 35         36 18         12 24 12             9 3   6                   1 172     1         260   141 141   141 135             92   43 43   43 41                                         1 173   173 173   173 69 69     104 33 33     71 71 71       1    
Backbone.Picky = (function (Backbone, _) {
  var Picky = {};
 
  // Picky.SingleSelect
  // ------------------
  // A single-select mixin for Backbone.Collection, allowing a single
  // model to be selected within a collection. Selection of another
  // model within the collection causes the previous model to be
  // deselected.
 
  Picky.SingleSelect = function(collection){
    this.collection = collection;
  };
 
  _.extend(Picky.SingleSelect.prototype, {
 
    // Select a model, deselecting any previously
    // selected model
    select: function(model){
      if (model && this.selected === model) { return; }
 
      this.deselect();
 
      this.selected = model;
      this.selected.select();
      this.trigger("select:one", model);
    },
 
    // Deselect a model, resulting in no model
    // being selected
    deselect: function(model){
      if (!this.selected){ return; }
 
      model = model || this.selected;
      if (this.selected !== model){ return; }
 
      this.selected.deselect();
      this.trigger("deselect:one", this.selected);
      delete this.selected;
    }
 
  });
 
  // Picky.MultiSelect
  // -----------------
  // A mult-select mixin for Backbone.Collection, allowing a collection to
  // have multiple items selected, including `selectAll` and `selectNone`
  // capabilities.
 
  Picky.MultiSelect = function (collection) {
    this.collection = collection;
    this.selected = {};
  };
 
  _.extend(Picky.MultiSelect.prototype, {
 
    // Select a specified model, make sure the
    // model knows it's selected, and hold on to
    // the selected model.
    select: function (model) {
      if (this.selected[model.cid]) { return; }
 
      this.selected[model.cid] = model;
      model.select();
      calculateSelectedLength(this);
    },
 
    // Deselect a specified model, make sure the
    // model knows it has been deselected, and remove
    // the model from the selected list.
    deselect: function (model) {
      if (!this.selected[model.cid]) { return; }
 
      delete this.selected[model.cid];
      model.deselect();
      calculateSelectedLength(this);
    },
 
    // Select all models in this collection
    selectAll: function () {
      this.each(function (model) { model.select(); });
      calculateSelectedLength(this);
    },
 
    // Deselect all models in this collection
    selectNone: function () {
      Iif (this.selectedLength === 0) { return; }
      this.each(function (model) { model.deselect(); });
      calculateSelectedLength(this);
    },
 
    // Toggle select all / none. If some are selected, it
    // will select all. If all are selected, it will select 
    // none. If none are selected, it will select all.
    toggleSelectAll: function () {
      if (this.selectedLength === this.length) {
        this.selectNone();
      } else {
        this.selectAll();
      }
    }
  });
 
  // Picky.Selectable
  // ----------------
  // A selectable mixin for Backbone.Model, allowing a model to be selected,
  // enabling it to work with Picky.MultiSelect or on it's own
 
  Picky.Selectable = function (model) {
    this.model = model;
  };
 
  _.extend(Picky.Selectable.prototype, {
 
    // Select this model, and tell our
    // collection that we're selected
    select: function () {
      if (this.selected) { return; }
 
      this.selected = true;
      this.trigger("selected", this);
 
      if (this.collection) {
        this.collection.select(this);
      }
    },
 
    // Deselect this model, and tell our
    // collection that we're deselected
    deselect: function () {
      if (!this.selected) { return; }
 
      this.selected = false;
      this.trigger("deselected", this);
 
      if (this.collection) {
        this.collection.deselect(this);
      }
    },
 
    // Change selected to the opposite of what
    // it currently is
    toggleSelected: function () {
      if (this.selected) {
        this.deselect();
      } else {
        this.select();
      }
    }
  });
 
  // Helper Methods
  // --------------
 
  // Calculate the number of selected items in a collection
  // and update the collection with that length. Trigger events
  // from the collection based on the number of selected items.
  var calculateSelectedLength = function (collection) {
    collection.selectedLength = _.size(collection.selected);
 
    var selectedLength = collection.selectedLength;
    var length = collection.length;
 
    if (selectedLength === length) {
      collection.trigger("select:all", collection);
      return;
    }
 
    if (selectedLength === 0) {
      collection.trigger("select:none", collection);
      return;
    }
 
    Eif (selectedLength > 0 && selectedLength < length) {
      collection.trigger("select:some", collection);
      return;
    }
  };
 
  return Picky;
})(Backbone, _);