drupal-civicrm/sites/all/modules/civicrm/packages/backbone/backbone.collectionsubset.js

234 lines
6.7 KiB
JavaScript
Raw Permalink Normal View History

2018-01-14 15:10:16 +02:00
/*! backbone.collectionsubset - v0.1.2 - 2012-12-20
* https://github.com/anthonyshort/backbone.collectionsubset
* Copyright (c) 2012 Anthony Short; Licensed MIT */
// Patched for civicrm by colemanw - added global import of _ variable
(function(_) {
Backbone.CollectionSubset = (function() {
CollectionSubset.extend = Backbone.Model.extend;
_.extend(CollectionSubset.prototype, Backbone.Events);
function CollectionSubset(options) {
if (options == null) {
options = {};
}
options = _.defaults(options, {
refresh: true,
triggers: null,
filter: function() {
return true;
},
name: null,
child: null,
parent: null
});
this.triggers = options.triggers ? options.triggers.split(' ') : [];
if (!options.child) {
options.child = new options.parent.constructor;
}
this.setParent(options.parent);
this.setChild(options.child);
this.setFilter(options.filter);
if (options.model) {
this.child.model = options.model;
}
if (options.refresh) {
this.refresh();
}
this.name = options.name;
}
CollectionSubset.prototype.setParent = function(collection) {
var _ref,
_this = this;
if ((_ref = this.parent) != null) {
_ref.off(null, null, this);
}
this.parent = collection;
this.parent.on('add', this._onParentAdd, this);
this.parent.on('remove', this._onParentRemove, this);
this.parent.on('reset', this._onParentReset, this);
this.parent.on('change', this._onParentChange, this);
this.parent.on('dispose', this.dispose, this);
this.parent.on('loading', (function() {
return _this.child.trigger('loading');
}), this);
return this.parent.on('ready', (function() {
return _this.child.trigger('ready');
}), this);
};
CollectionSubset.prototype.setChild = function(collection) {
var _ref;
if ((_ref = this.child) != null) {
_ref.off(null, null, this);
}
this.child = collection;
this.child.on('add', this._onChildAdd, this);
this.child.on('reset', this._onChildReset, this);
this.child.on('dispose', this.dispose, this);
this.child.superset = this.parent;
this.child.filterer = this;
this.child.url = this.parent.url;
return this.child.model = this.parent.model;
};
CollectionSubset.prototype.setFilter = function(fn) {
var filter;
filter = function(model) {
var matchesFilter, matchesParentFilter;
matchesFilter = fn.call(this, model);
matchesParentFilter = this.parent.filterer ? this.parent.filterer.filter(model) : true;
return matchesFilter && matchesParentFilter;
};
return this.filter = _.bind(filter, this);
};
CollectionSubset.prototype.refresh = function(options) {
var models;
if (options == null) {
options = {};
}
models = this.parent.filter(this.filter);
this.child.reset(models, {
subset: this
});
return this.child.trigger('refresh');
};
CollectionSubset.prototype._replaceChildModel = function(parentModel) {
var childModel, index;
childModel = this._getByCid(this.child, parentModel.cid);
if (childModel === parentModel) {
return;
}
if (_.isUndefined(childModel)) {
return this.child.add(parentModel, {
subset: this
});
} else {
index = this.child.indexOf(childModel);
this.child.remove(childModel);
return this.child.add(parentModel, {
at: index,
subset: this
});
}
};
CollectionSubset.prototype._onParentAdd = function(model, collection, options) {
if (options && options.subset === this) {
return;
}
if (this.filter(model)) {
return this._replaceChildModel(model);
}
};
CollectionSubset.prototype._onParentRemove = function(model, collection, options) {
return this.child.remove(model, options);
};
CollectionSubset.prototype._onParentReset = function(collection, options) {
return this.refresh();
};
CollectionSubset.prototype._onParentChange = function(model, changes) {
if (!this.triggerMatched(model)) {
return;
}
if (this.filter(model)) {
return this.child.add(model);
} else {
return this.child.remove(model);
}
};
CollectionSubset.prototype._onChildAdd = function(model, collection, options) {
var parentModel;
if (options && options.subset === this) {
return;
}
this.parent.add(model);
parentModel = this._getByCid(this.parent, model.cid);
if (!parentModel) {
return;
}
if (this.filter(parentModel)) {
return this._replaceChildModel(parentModel);
} else {
return this.child.remove(model);
}
};
CollectionSubset.prototype._onChildReset = function(collection, options) {
if (options && options.subset === this) {
return;
}
this.parent.add(this.child.models);
return this.refresh();
};
CollectionSubset.prototype._getByCid = function(model, cid) {
var fn;
fn = model.getByCid || model.get;
return fn.apply(model, [cid]);
};
CollectionSubset.prototype.triggerMatched = function(model) {
var changedAttrs;
if (this.triggers.length === 0) {
return true;
}
if (!model.hasChanged()) {
return false;
}
changedAttrs = _.keys(model.changedAttributes());
return _.intersection(this.triggers, changedAttrs).length > 0;
};
CollectionSubset.prototype.dispose = function() {
var prop, _base, _i, _len, _ref;
if (this.disposed) {
return;
}
this.trigger('dispose', this);
this.parent.off(null, null, this);
this.child.off(null, null, this);
if (typeof (_base = this.child).dispose === "function") {
_base.dispose();
}
this.off();
_ref = ['parent', 'child', 'options'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
prop = _ref[_i];
delete this[prop];
}
return this.disposed = true;
};
return CollectionSubset;
})();
Backbone.Collection.prototype.subcollection = function(options) {
var subset;
if (options == null) {
options = {};
}
_.defaults(options, {
child: new this.constructor,
parent: this
});
subset = new Backbone.CollectionSubset(options);
return subset.child;
};
if (typeof module !== "undefined" && module !== null) {
module.exports = Backbone.CollectionSubset;
}
}(_));