Create new view id the current one isn't in the project or if it's the first one (so we let the first one always unchanged)
Otherwise modify the current one
(function(root) {
"use strict";
var Backbone = root.Backbone;
var Models = root.Rkns.Models = {};
Models.getUID = function(obj) {
var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
function(c) {
var r = Math.random() * 16 | 0, v = c === 'x' ? r
: (r & 0x3 | 0x8);
return v.toString(16);
});
if (typeof obj !== 'undefined') {
return obj.type + "-" + guid;
}
else {
return guid;
}
};
var RenkanModel = Backbone.RelationalModel.extend({
idAttribute : "_id",
constructor : function(options) {
if (typeof options !== "undefined") {
options._id = options._id || options.id || Models.getUID(this);
options.title = options.title || "";
options.description = options.description || "";
options.uri = options.uri || "";
if (typeof this.prepare === "function") {
options = this.prepare(options);
}
}
Backbone.RelationalModel.prototype.constructor.call(this, options);
},
validate : function() {
if (!this.type) {
return "object has no type";
}
},
addReference : function(_options, _propName, _list, _id, _default) {
var _element = _list.get(_id);
if (typeof _element === "undefined" &&
typeof _default !== "undefined") {
_options[_propName] = _default;
}
else {
_options[_propName] = _element;
}
}
});
// USER
var User = Models.User = RenkanModel.extend({
type : "user",
prepare : function(options) {
options.color = options.color || "#666666";
return options;
},
toJSON : function() {
return {
_id : this.get("_id"),
title : this.get("title"),
uri : this.get("uri"),
description : this.get("description"),
color : this.get("color")
};
}
});
// NODE
var Node = Models.Node = RenkanModel.extend({
type : "node",
relations : [ {
type : Backbone.HasOne,
key : "created_by",
relatedModel : User
} ],
prepare : function(options) {
var project = options.project;
this.addReference(options, "created_by", project.get("users"),
options.created_by, project.current_user);
options.description = options.description || "";
return options;
},
toJSON : function() {
return {
_id : this.get("_id"),
title : this.get("title"),
uri : this.get("uri"),
description : this.get("description"),
position : this.get("position"),
image : this.get("image"),
style : this.get("style"),
created_by : this.get("created_by") ? this.get("created_by")
.get("_id") : null,
size : this.get("size"),
clip_path : this.get("clip_path"),
shape : this.get("shape"),
type : this.get("type")
};
}
});
// EDGE
var Edge = Models.Edge = RenkanModel.extend({
type : "edge",
relations : [ {
type : Backbone.HasOne,
key : "created_by",
relatedModel : User
}, {
type : Backbone.HasOne,
key : "from",
relatedModel : Node
}, {
type : Backbone.HasOne,
key : "to",
relatedModel : Node
} ],
prepare : function(options) {
var project = options.project;
this.addReference(options, "created_by", project.get("users"),
options.created_by, project.current_user);
this.addReference(options, "from", project.get("nodes"),
options.from);
this.addReference(options, "to", project.get("nodes"), options.to);
return options;
},
toJSON : function() {
return {
_id : this.get("_id"),
title : this.get("title"),
uri : this.get("uri"),
description : this.get("description"),
from : this.get("from") ? this.get("from").get("_id") : null,
to : this.get("to") ? this.get("to").get("_id") : null,
style : this.get("style"),
created_by : this.get("created_by") ? this.get("created_by")
.get("_id") : null
};
}
});
// View
var View = Models.View = RenkanModel.extend({
type : "view",
relations : [ {
type : Backbone.HasOne,
key : "created_by",
relatedModel : User
} ],
prepare : function(options) {
var project = options.project;
this.addReference(options, "created_by", project.get("users"),
options.created_by, project.current_user);
options.description = options.description || "";
if (typeof options.offset !== "undefined") {
var offset = {};
if (Array.isArray(options.offset)) {
offset.x = options.offset[0];
offset.y = options.offset.length > 1 ? options.offset[1]
: options.offset[0];
}
else if (options.offset.x != null) {
offset.x = options.offset.x;
offset.y = options.offset.y;
}
options.offset = offset;
}
return options;
},
toJSON : function() {
return {
_id : this.get("_id"),
zoom_level : this.get("zoom_level"),
offset : this.get("offset"),
title : this.get("title"),
description : this.get("description"),
created_by : this.get("created_by") ? this.get("created_by")
.get("_id") : null,
hidden_nodes: this.get("hidden_nodes")
// Don't need project id
};
}
});
// PROJECT
var Project = Models.Project = RenkanModel.extend({
schema_version : "2",
type : "project",
blacklist : [ 'saveStatus', 'loadingStatus'],
relations : [ {
type : Backbone.HasMany,
key : "users",
relatedModel : User,
reverseRelation : {
key : 'project',
includeInJSON : '_id'
}
}, {
type : Backbone.HasMany,
key : "nodes",
relatedModel : Node,
reverseRelation : {
key : 'project',
includeInJSON : '_id'
}
}, {
type : Backbone.HasMany,
key : "edges",
relatedModel : Edge,
reverseRelation : {
key : 'project',
includeInJSON : '_id'
}
}, {
type : Backbone.HasMany,
key : "views",
relatedModel : View,
reverseRelation : {
key : 'project',
includeInJSON : '_id'
}
} ],
addUser : function(_props, _options) {
_props.project = this;
var _user = User.findOrCreate(_props);
this.get("users").push(_user, _options);
return _user;
},
addNode : function(_props, _options) {
_props.project = this;
var _node = Node.findOrCreate(_props);
this.get("nodes").push(_node, _options);
return _node;
},
addEdge : function(_props, _options) {
_props.project = this;
var _edge = Edge.findOrCreate(_props);
this.get("edges").push(_edge, _options);
return _edge;
},
addView : function(_props, _options) {
_props.project = this;
// TODO: check if need to replace with create only
var _view = View.findOrCreate(_props);
// TODO: Should we remember only one view?
this.get("views").push(_view, _options);
return _view;
},
removeNode : function(_model) {
this.get("nodes").remove(_model);
},
removeEdge : function(_model) {
this.get("edges").remove(_model);
},
validate : function(options) {
var _project = this;
_.each(
[].concat(options.users, options.nodes, options.edges,options.views),
function(_item) {
if (_item) {
_item.project = _project;
}
}
);
},
getSchemaVersion : function(data) {
var t = data;
if(typeof(t) === "undefined") {
t = this;
}
var version = t.schema_version;
if(!version) {
return 1;
}
else {
return version;
}
},
// Add event handler to remove edges when a node is removed
initialize : function() {
var _this = this;
this.on("remove:nodes", function(_node) {
_this.get("edges").remove(
_this.get("edges").filter(
function(_edge) {
return _edge.get("from") === _node ||
_edge.get("to") === _node;
}));
});
},
toJSON : function() {
var json = _.clone(this.attributes);
for ( var attr in json) {
if ((json[attr] instanceof Backbone.Model) ||
(json[attr] instanceof Backbone.Collection) ||
(json[attr] instanceof RenkanModel)) {
json[attr] = json[attr].toJSON();
}
}
return _.omit(json, this.blacklist);
}
});
var RosterUser = Models.RosterUser = Backbone.Model
.extend({
type : "roster_user",
idAttribute : "_id",
constructor : function(options) {
if (typeof options !== "undefined") {
options._id = options._id ||
options.id ||
Models.getUID(this);
options.title = options.title || "(untitled " + this.type + ")";
options.description = options.description || "";
options.uri = options.uri || "";
options.project = options.project || null;
options.site_id = options.site_id || 0;
if (typeof this.prepare === "function") {
options = this.prepare(options);
}
}
Backbone.Model.prototype.constructor.call(this, options);
},
validate : function() {
if (!this.type) {
return "object has no type";
}
},
prepare : function(options) {
options.color = options.color || "#666666";
return options;
},
toJSON : function() {
return {
_id : this.get("_id"),
title : this.get("title"),
uri : this.get("uri"),
description : this.get("description"),
color : this.get("color"),
project : (this.get("project") != null) ? this.get(
"project").get("id") : null,
site_id : this.get("site_id")
};
}
});
var UsersList = Models.UsersList = Backbone.Collection.extend({
model : RosterUser
});
})(window);