bamjs
Version:
Backbone with modifications. Adds heirarchy to Views, derived properties on Models and general utility.
249 lines (196 loc) • 6.04 kB
JavaScript
// Generated by CoffeeScript 1.8.0
(function() {
var Backbone, View, difference, without, _ref,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
__slice = [].slice;
Backbone = require('./backbone');
_ref = require('./underscore'), without = _ref.without, difference = _ref.difference;
View = (function(_super) {
__extends(View, _super);
View.prototype.parent = null;
View.prototype.children = null;
View.prototype.namespace = '';
/*
Ensure the classname is applied, then set the parent and children if any
are passed in. Does the normal backbone constructor and then does the
first state change.
*/
function View(options) {
var _ref1;
if (options == null) {
options = {};
}
this.children = [];
if (options.className) {
this.className = options.className;
}
if (options.namespace) {
this.namespace = options.namespace;
}
if (options.el) {
this._ensureClass(options.el);
}
if (options.parent) {
this.setParent(options.parent);
}
if ((_ref1 = options.children) != null ? _ref1.length : void 0) {
this.addChildren(options.children);
}
View.__super__.constructor.call(this, options);
}
/*
Used to ensure that the className property of the view is applied to an
el passed in as an option.
*/
View.prototype._ensureClass = function(el, className) {
if (className == null) {
className = this.className;
}
return Backbone.$(el).addClass(className);
};
/*
Adds a list of views as children of this view.
*/
View.prototype.addChildren = function(views) {
var view, _i, _len, _results;
_results = [];
for (_i = 0, _len = views.length; _i < _len; _i++) {
view = views[_i];
_results.push(this.addChild(view));
}
return _results;
};
/*
Adds a view as a child of this view.
*/
View.prototype.addChild = function(view) {
if (view.parent) {
view.unsetParent();
}
this.children.push(view);
return view.parent = this;
};
/*
Sets the parent view.
*/
View.prototype.setParent = function(parent) {
if (this.parent) {
this.unsetParent();
}
this.parent = parent;
return this.parent.children.push(this);
};
/*
Unsets the parent view.
*/
View.prototype.unsetParent = function() {
if (!this.parent) {
return;
}
return this.parent.removeChild(this);
};
/*
Parent and Child accessors.
*/
View.prototype.hasParent = function() {
return !!this.parent;
};
View.prototype.getParent = function() {
return this.parent;
};
View.prototype.hasChildren = function() {
return this.children.length;
};
View.prototype.getChildren = function() {
return this.children;
};
View.prototype.hasChild = function(view) {
return __indexOf.call(this.children, view) >= 0;
};
View.prototype.hasDescendant = function(view) {
var child, _i, _len, _ref1;
if (__indexOf.call(this.children, view) >= 0) {
return true;
}
_ref1 = this.children;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
child = _ref1[_i];
if (child.hasDescendant(view)) {
return true;
}
}
return false;
};
/*
Removing children
*/
View.prototype.removeChild = function(child) {
this.children = without(this.children, child);
return child.parent = null;
};
View.prototype.removeChildren = function(children) {
var child, _i, _len, _ref1, _results;
_ref1 = this.children;
_results = [];
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
child = _ref1[_i];
_results.push(this.removeChild(child));
}
return _results;
};
/*
Gets the root view for a particular view. Can be itself.
*/
View.prototype.root = function() {
var root;
root = this;
while (root.hasParent()) {
root = root.getParent();
}
return root;
};
/*
Calls remove on all child views before removing itself
*/
View.prototype.remove = function() {
this.children.forEach(function(child) {
return child.remove();
});
this.children = [];
this.parent = null;
this.off();
this.undelegateEvents();
return View.__super__.remove.call(this);
};
/*
Calls trigger on the root() object with the namespace added, and also on
itself without the namespace.
*/
View.prototype.trigger = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
Backbone.View.prototype.trigger.apply(this, args);
if (this.namespace) {
args[0] = this.namespace + '.' + args[0];
}
if (this.parent) {
return this.parent._bubbleTrigger.apply(this.parent, args);
}
};
/*
Used when bubbling to prevent namespace pollution as it goes up the chain.
*/
View.prototype._bubbleTrigger = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
Backbone.View.prototype.trigger.apply(this, args);
if (this.parent) {
return this.parent._bubbleTrigger.apply(this.parent, args);
}
};
return View;
})(Backbone.View);
module.exports = View;
}).call(this);