diff --git a/app/assets/javascripts/src/Metamaps.Backbone.js b/app/assets/javascripts/src/Metamaps.Backbone.js index 25c92fc9..63025c54 100644 --- a/app/assets/javascripts/src/Metamaps.Backbone.js +++ b/app/assets/javascripts/src/Metamaps.Backbone.js @@ -5,10 +5,24 @@ * * Dependencies: * - Metamaps.Active + * - Metamaps.Collaborators + * - Metamaps.Creators + * - Metamaps.Filter + * - Metamaps.JIT * - Metamaps.Loading * - Metamaps.Map * - Metamaps.Mapper + * - Metamaps.Mappers + * - Metamaps.Mappings + * - Metamaps.Metacodes * - Metamaps.Realtime + * - Metamaps.Synapse + * - Metamaps.SynapseCard + * - Metamaps.Synapses + * - Metamaps.Topic + * - Metamaps.TopicCard + * - Metamaps.Topics + * - Metamaps.Visualize */ Metamaps.Backbone = {} @@ -48,13 +62,13 @@ Metamaps.Backbone.Map = Backbone.Model.extend({ }, authorizeToEdit: function (mapper) { if (mapper && ( - this.get('permission') === 'commons' || - this.get('collaborator_ids').includes(mapper.get('id')) || - this.get('user_id') === mapper.get('id'))) { + this.get('permission') === 'commons' || + this.get('collaborator_ids').includes(mapper.get('id')) || + this.get('user_id') === mapper.get('id'))) { return true } else { return false - } + } }, authorizePermissionChange: function (mapper) { if (mapper && this.get('user_id') === mapper.get('id')) { @@ -264,3 +278,446 @@ Metamaps.Backbone.MapperCollection = Backbone.Collection.extend({ model: Metamaps.Backbone.Mapper, url: '/users' }) + +Metamaps.Backbone.init = function () { + var self = Metamaps.Backbone + + self.Metacode = Backbone.Model.extend({ + initialize: function () { + var image = new Image() + image.crossOrigin = 'Anonymous' + image.src = this.get('icon') + this.set('image', image) + }, + prepareLiForFilter: function () { + var li = '' + li += '
  • ' + li += '' + li += '

    ' + this.get('name').toLowerCase() + '

  • ' + return li + } + + }) + self.MetacodeCollection = Backbone.Collection.extend({ + model: this.Metacode, + url: '/metacodes', + comparator: function (a, b) { + a = a.get('name').toLowerCase() + b = b.get('name').toLowerCase() + return a > b ? 1 : a < b ? -1 : 0 + } + }) + + self.Topic = Backbone.Model.extend({ + urlRoot: '/topics', + blacklist: ['node', 'created_at', 'updated_at', 'user_name', 'user_image', 'map_count', 'synapse_count'], + toJSON: function (options) { + return _.omit(this.attributes, this.blacklist) + }, + save: function (key, val, options) { + var attrs + + // Handle both `"key", value` and `{key: value}` -style arguments. + if (key == null || typeof key === 'object') { + attrs = key + options = val + } else { + (attrs = {})[key] = val + } + + var newOptions = options || {} + var s = newOptions.success + + var permBefore = this.get('permission') + + newOptions.success = function (model, response, opt) { + if (s) s(model, response, opt) + model.trigger('saved') + + if (permBefore === 'private' && model.get('permission') !== 'private') { + model.trigger('noLongerPrivate') + } + else if (permBefore !== 'private' && model.get('permission') === 'private') { + model.trigger('nowPrivate') + } + } + return Backbone.Model.prototype.save.call(this, attrs, newOptions) + }, + initialize: function () { + if (this.isNew()) { + this.set({ + 'user_id': Metamaps.Active.Mapper.id, + 'desc': '', + 'link': '', + 'permission': Metamaps.Active.Map ? Metamaps.Active.Map.get('permission') : 'commons' + }) + } + + this.on('changeByOther', this.updateCardView) + this.on('change', this.updateNodeView) + this.on('saved', this.savedEvent) + this.on('nowPrivate', function () { + var removeTopicData = { + mappableid: this.id + } + + $(document).trigger(Metamaps.JIT.events.removeTopic, [removeTopicData]) + }) + this.on('noLongerPrivate', function () { + var newTopicData = { + mappingid: this.getMapping().id, + mappableid: this.id + } + + $(document).trigger(Metamaps.JIT.events.newTopic, [newTopicData]) + }) + + this.on('change:metacode_id', Metamaps.Filter.checkMetacodes, this) + }, + authorizeToEdit: function (mapper) { + if (mapper && + (this.get('calculated_permission') === 'commons' || + this.get('collaborator_ids').includes(mapper.get('id')) || + this.get('user_id') === mapper.get('id'))) { + return true + } else { + return false + } + }, + authorizePermissionChange: function (mapper) { + if (mapper && this.get('user_id') === mapper.get('id')) return true + else return false + }, + getDate: function () {}, + getMetacode: function () { + return Metamaps.Metacodes.get(this.get('metacode_id')) + }, + getMapping: function () { + if (!Metamaps.Active.Map) return false + + return Metamaps.Mappings.findWhere({ + map_id: Metamaps.Active.Map.id, + mappable_type: 'Topic', + mappable_id: this.isNew() ? this.cid : this.id + }) + }, + createNode: function () { + var mapping + var node = { + adjacencies: [], + id: this.isNew() ? this.cid : this.id, + name: this.get('name') + } + + if (Metamaps.Active.Map) { + mapping = this.getMapping() + node.data = { + $mapping: null, + $mappingID: mapping.id + } + } + + return node + }, + updateNode: function () { + var mapping + var node = this.get('node') + node.setData('topic', this) + + if (Metamaps.Active.Map) { + mapping = this.getMapping() + node.setData('mapping', mapping) + } + + return node + }, + savedEvent: function () { + Metamaps.Realtime.sendTopicChange(this) + }, + updateViews: function () { + var onPageWithTopicCard = Metamaps.Active.Map || Metamaps.Active.Topic + var node = this.get('node') + // update topic card, if this topic is the one open there + if (onPageWithTopicCard && this == Metamaps.TopicCard.openTopicCard) { + Metamaps.TopicCard.showCard(node) + } + + // update the node on the map + if (onPageWithTopicCard && node) { + node.name = this.get('name') + Metamaps.Visualize.mGraph.plot() + } + }, + updateCardView: function () { + var onPageWithTopicCard = Metamaps.Active.Map || Metamaps.Active.Topic + var node = this.get('node') + // update topic card, if this topic is the one open there + if (onPageWithTopicCard && this == Metamaps.TopicCard.openTopicCard) { + Metamaps.TopicCard.showCard(node) + } + }, + updateNodeView: function () { + var onPageWithTopicCard = Metamaps.Active.Map || Metamaps.Active.Topic + var node = this.get('node') + + // update the node on the map + if (onPageWithTopicCard && node) { + node.name = this.get('name') + Metamaps.Visualize.mGraph.plot() + } + } + }) + + self.TopicCollection = Backbone.Collection.extend({ + model: self.Topic, + url: '/topics' + }) + + self.Synapse = Backbone.Model.extend({ + urlRoot: '/synapses', + blacklist: ['edge', 'created_at', 'updated_at'], + toJSON: function (options) { + return _.omit(this.attributes, this.blacklist) + }, + save: function (key, val, options) { + var attrs + + // Handle both `"key", value` and `{key: value}` -style arguments. + if (key == null || typeof key === 'object') { + attrs = key + options = val + } else { + (attrs = {})[key] = val + } + + var newOptions = options || {} + var s = newOptions.success + + var permBefore = this.get('permission') + + newOptions.success = function (model, response, opt) { + if (s) s(model, response, opt) + model.trigger('saved') + + if (permBefore === 'private' && model.get('permission') !== 'private') { + model.trigger('noLongerPrivate') + } + else if (permBefore !== 'private' && model.get('permission') === 'private') { + model.trigger('nowPrivate') + } + } + return Backbone.Model.prototype.save.call(this, attrs, newOptions) + }, + initialize: function () { + if (this.isNew()) { + this.set({ + 'user_id': Metamaps.Active.Mapper.id, + 'permission': Metamaps.Active.Map ? Metamaps.Active.Map.get('permission') : 'commons', + 'category': 'from-to' + }) + } + + this.on('changeByOther', this.updateCardView) + this.on('change', this.updateEdgeView) + this.on('saved', this.savedEvent) + this.on('noLongerPrivate', function () { + var newSynapseData = { + mappingid: this.getMapping().id, + mappableid: this.id + } + + $(document).trigger(Metamaps.JIT.events.newSynapse, [newSynapseData]) + }) + this.on('nowPrivate', function () { + $(document).trigger(Metamaps.JIT.events.removeSynapse, [{ + mappableid: this.id + }]) + }) + + this.on('change:desc', Metamaps.Filter.checkSynapses, this) + }, + prepareLiForFilter: function () { + var li = '' + li += '
  • ' + li += '
  • ' + return li + }, + authorizeToEdit: function (mapper) { + if (mapper && (this.get('calculated_permission') === 'commons' || this.get('collaborator_ids').includes(mapper.get('id')) || this.get('user_id') === mapper.get('id'))) return true + else return false + }, + authorizePermissionChange: function (mapper) { + if (mapper && this.get('user_id') === mapper.get('id')) return true + else return false + }, + getTopic1: function () { + return Metamaps.Topics.get(this.get('node1_id')) + }, + getTopic2: function () { + return Metamaps.Topics.get(this.get('node2_id')) + }, + getDirection: function () { + var t1 = this.getTopic1(), + t2 = this.getTopic2() + + return t1 && t2 ? [ + t1.get('node').id, + t2.get('node').id + ] : false + }, + getMapping: function () { + if (!Metamaps.Active.Map) return false + + return Metamaps.Mappings.findWhere({ + map_id: Metamaps.Active.Map.id, + mappable_type: 'Synapse', + mappable_id: this.isNew() ? this.cid : this.id + }) + }, + createEdge: function (providedMapping) { + var mapping, mappingID + var synapseID = this.isNew() ? this.cid : this.id + + var edge = { + nodeFrom: this.get('node1_id'), + nodeTo: this.get('node2_id'), + data: { + $synapses: [], + $synapseIDs: [synapseID], + } + } + + if (Metamaps.Active.Map) { + mapping = providedMapping || this.getMapping() + mappingID = mapping.isNew() ? mapping.cid : mapping.id + edge.data.$mappings = [] + edge.data.$mappingIDs = [mappingID] + } + + return edge + }, + updateEdge: function () { + var mapping + var edge = this.get('edge') + edge.getData('synapses').push(this) + + if (Metamaps.Active.Map) { + mapping = this.getMapping() + edge.getData('mappings').push(mapping) + } + + return edge + }, + savedEvent: function () { + Metamaps.Realtime.sendSynapseChange(this) + }, + updateViews: function () { + this.updateCardView() + this.updateEdgeView() + }, + updateCardView: function () { + var onPageWithSynapseCard = Metamaps.Active.Map || Metamaps.Active.Topic + var edge = this.get('edge') + + // update synapse card, if this synapse is the one open there + if (onPageWithSynapseCard && edge == Metamaps.SynapseCard.openSynapseCard) { + Metamaps.SynapseCard.showCard(edge) + } + }, + updateEdgeView: function () { + var onPageWithSynapseCard = Metamaps.Active.Map || Metamaps.Active.Topic + var edge = this.get('edge') + + // update the edge on the map + if (onPageWithSynapseCard && edge) { + Metamaps.Visualize.mGraph.plot() + } + } + }) + + self.SynapseCollection = Backbone.Collection.extend({ + model: self.Synapse, + url: '/synapses' + }) + + self.Mapping = Backbone.Model.extend({ + urlRoot: '/mappings', + blacklist: ['created_at', 'updated_at'], + toJSON: function (options) { + return _.omit(this.attributes, this.blacklist) + }, + initialize: function () { + if (this.isNew()) { + this.set({ + 'user_id': Metamaps.Active.Mapper.id, + 'map_id': Metamaps.Active.Map ? Metamaps.Active.Map.id : null + }) + } + }, + getMap: function () { + return Metamaps.Map.get(this.get('map_id')) + }, + getTopic: function () { + if (this.get('mappable_type') === 'Topic') return Metamaps.Topic.get(this.get('mappable_id')) + else return false + }, + getSynapse: function () { + if (this.get('mappable_type') === 'Synapse') return Metamaps.Synapse.get(this.get('mappable_id')) + else return false + } + }) + + self.MappingCollection = Backbone.Collection.extend({ + model: self.Mapping, + url: '/mappings' + }) + + Metamaps.Metacodes = Metamaps.Metacodes ? new self.MetacodeCollection(Metamaps.Metacodes) : new self.MetacodeCollection() + + Metamaps.Topics = Metamaps.Topics ? new self.TopicCollection(Metamaps.Topics) : new self.TopicCollection() + + Metamaps.Synapses = Metamaps.Synapses ? new self.SynapseCollection(Metamaps.Synapses) : new self.SynapseCollection() + + Metamaps.Mappers = Metamaps.Mappers ? new self.MapperCollection(Metamaps.Mappers) : new self.MapperCollection() + + Metamaps.Collaborators = Metamaps.Collaborators ? new self.MapperCollection(Metamaps.Collaborators) : new self.MapperCollection() + + // this is for topic view + Metamaps.Creators = Metamaps.Creators ? new self.MapperCollection(Metamaps.Creators) : new self.MapperCollection() + + if (Metamaps.Active.Map) { + Metamaps.Mappings = Metamaps.Mappings ? new self.MappingCollection(Metamaps.Mappings) : new self.MappingCollection() + + Metamaps.Active.Map = new self.Map(Metamaps.Active.Map) + } + + if (Metamaps.Active.Topic) Metamaps.Active.Topic = new self.Topic(Metamaps.Active.Topic) + + // attach collection event listeners + self.attachCollectionEvents = function () { + Metamaps.Topics.on('add remove', function (topic) { + Metamaps.Map.InfoBox.updateNumbers() + Metamaps.Filter.checkMetacodes() + Metamaps.Filter.checkMappers() + }) + + Metamaps.Synapses.on('add remove', function (synapse) { + Metamaps.Map.InfoBox.updateNumbers() + Metamaps.Filter.checkSynapses() + Metamaps.Filter.checkMappers() + }) + + if (Metamaps.Active.Map) { + Metamaps.Mappings.on('add remove', function (mapping) { + Metamaps.Map.InfoBox.updateNumbers() + Metamaps.Filter.checkSynapses() + Metamaps.Filter.checkMetacodes() + Metamaps.Filter.checkMappers() + }) + } + } + self.attachCollectionEvents() +}; // end Metamaps.Backbone.init diff --git a/app/assets/javascripts/src/Metamaps.js.erb b/app/assets/javascripts/src/Metamaps.js.erb index 666ad66d..e4b64f14 100644 --- a/app/assets/javascripts/src/Metamaps.js.erb +++ b/app/assets/javascripts/src/Metamaps.js.erb @@ -1,25 +1,27 @@ // TODO document this user agent function -var labelType, useGradients, nativeTextSupport, animate; -(function () { - var ua = navigator.userAgent, - iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i), - typeOfCanvas = typeof HTMLCanvasElement, - nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'), - textSupport = nativeCanvasSupport && (typeof document.createElement('canvas').getContext('2d').fillText == 'function'); - //I'm setting this based on the fact that ExCanvas provides text support for IE - //and that as of today iPhone/iPad current text support is lame - labelType = (!nativeCanvasSupport || (textSupport && !iStuff)) ? 'Native' : 'HTML'; - nativeTextSupport = labelType == 'Native'; - useGradients = nativeCanvasSupport; - animate = !(iStuff || !nativeCanvasSupport); -})(); +var labelType, useGradients, nativeTextSupport, animate +;(function () { + var ua = navigator.userAgent, + iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i), + typeOfCanvas = typeof HTMLCanvasElement, + nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'), + textSupport = nativeCanvasSupport && (typeof document.createElement('canvas').getContext('2d').fillText == 'function') + // I'm setting this based on the fact that ExCanvas provides text support for IE + // and that as of today iPhone/iPad current text support is lame + labelType = (!nativeCanvasSupport || (textSupport && !iStuff)) ? 'Native' : 'HTML' + nativeTextSupport = labelType == 'Native' + useGradients = nativeCanvasSupport + animate = !(iStuff || !nativeCanvasSupport) +})() // TODO eliminate these 5 top-level variables -Metamaps.panningInt = null; -Metamaps.tempNode = null; -Metamaps.tempInit = false; -Metamaps.tempNode2 = null; +Metamaps.panningInt = null +Metamaps.tempNode = null +Metamaps.tempInit = false +Metamaps.tempNode2 = null Metamaps.VERSION = '<%= METAMAPS_VERSION %>' + +/* erb variables from rails */ Metamaps.Erb = {} Metamaps.Erb['REALTIME_SERVER'] = '<%= ENV['REALTIME_SERVER'] %>' Metamaps.Erb['junto_spinner_darkgrey.gif'] = '<%= asset_path('junto_spinner_darkgrey.gif') %>' @@ -27,510 +29,55 @@ Metamaps.Erb['user.png'] = '<%= asset_path('user.png') %>' Metamaps.Erb['icons/wildcard.png'] = '<%= asset_path('icons/wildcard.png') %>' Metamaps.Erb['topic_description_signifier.png'] = '<%= asset_path('topic_description_signifier.png') %>' Metamaps.Erb['topic_link_signifier.png'] = '<%= asset_path('topic_link_signifier.png') %>' +Metamaps.Erb['synapse16.png'] = '<%= asset_path('synapse16.png') %>' Metamaps.Settings = { - embed: false, // indicates that the app is on a page that is optimized for embedding in iFrames on other web pages - sandbox: false, // puts the app into a mode (when true) where it only creates data locally, and isn't writing it to the database - colors: { - background: '#344A58', - synapses: { - normal: '#888888', - hover: '#888888', - selected: '#FFFFFF' - }, - topics: { - selected: '#FFFFFF' - }, - labels: { - background: '#18202E', - text: '#DDD' - } + embed: false, // indicates that the app is on a page that is optimized for embedding in iFrames on other web pages + sandbox: false, // puts the app into a mode (when true) where it only creates data locally, and isn't writing it to the database + colors: { + background: '#344A58', + synapses: { + normal: '#888888', + hover: '#888888', + selected: '#FFFFFF' }, -}; + topics: { + selected: '#FFFFFF' + }, + labels: { + background: '#18202E', + text: '#DDD' + } + }, +} Metamaps.Touch = { - touchPos: null, // this stores the x and y values of a current touch event - touchDragNode: null // this stores a reference to a JIT node that is being dragged -}; + touchPos: null, // this stores the x and y values of a current touch event + touchDragNode: null // this stores a reference to a JIT node that is being dragged +} Metamaps.Mouse = { - didPan: false, - didBoxZoom: false, - changeInX: 0, - changeInY: 0, - edgeHoveringOver: false, - boxStartCoordinates: false, - boxEndCoordinates: false, - synapseStartCoordinates: [], - synapseEndCoordinates: null, - lastNodeClick: 0, - lastCanvasClick: 0, - DOUBLE_CLICK_TOLERANCE: 300 -}; + didPan: false, + didBoxZoom: false, + changeInX: 0, + changeInY: 0, + edgeHoveringOver: false, + boxStartCoordinates: false, + boxEndCoordinates: false, + synapseStartCoordinates: [], + synapseEndCoordinates: null, + lastNodeClick: 0, + lastCanvasClick: 0, + DOUBLE_CLICK_TOLERANCE: 300 +} Metamaps.Selected = { - reset: function () { - var self = Metamaps.Selected; + reset: function () { + var self = Metamaps.Selected - self.Nodes = []; - self.Edges = []; - }, - Nodes: [], - Edges: [] -}; - -/* - * - * BACKBONE - * - */ -Metamaps.Backbone.init = function () { - var self = Metamaps.Backbone; - - self.Metacode = Backbone.Model.extend({ - initialize: function () { - var image = new Image(); - image.crossOrigin = "Anonymous"; - image.src = this.get('icon'); - this.set('image',image); - }, - prepareLiForFilter: function () { - var li = ''; - li += '
  • ';       - li += '';       - li += '

    ' + this.get('name').toLowerCase() + '

  • '; - return li; - } - - }); - self.MetacodeCollection = Backbone.Collection.extend({ - model: this.Metacode, - url: '/metacodes', - comparator: function (a, b) { - a = a.get('name').toLowerCase(); - b = b.get('name').toLowerCase(); - return a > b ? 1 : a < b ? -1 : 0; - } - }); - - self.Topic = Backbone.Model.extend({ - urlRoot: '/topics', - blacklist: ['node', 'created_at', 'updated_at', 'user_name', 'user_image', 'map_count', 'synapse_count'], - toJSON: function (options) { - return _.omit(this.attributes, this.blacklist); - }, - save: function (key, val, options) { - - var attrs; - - // Handle both `"key", value` and `{key: value}` -style arguments. - if (key == null || typeof key === 'object') { - attrs = key; - options = val; - } else { - (attrs = {})[key] = val; - } - - var newOptions = options || {}; - var s = newOptions.success; - - var permBefore = this.get('permission'); - - newOptions.success = function (model, response, opt) { - if (s) s(model, response, opt); - model.trigger('saved'); - - if (permBefore === 'private' && model.get('permission') !== 'private') { - model.trigger('noLongerPrivate'); - } - else if (permBefore !== 'private' && model.get('permission') === 'private') { - model.trigger('nowPrivate'); - } - }; - return Backbone.Model.prototype.save.call(this, attrs, newOptions); - }, - initialize: function () { - if (this.isNew()) { - this.set({ - "user_id": Metamaps.Active.Mapper.id, - "desc": '', - "link": '', - "permission": Metamaps.Active.Map ? Metamaps.Active.Map.get('permission') : 'commons' - }); - } - - this.on('changeByOther', this.updateCardView); - this.on('change', this.updateNodeView); - this.on('saved', this.savedEvent); - this.on('nowPrivate', function(){ - var removeTopicData = { - mappableid: this.id - }; - - $(document).trigger(Metamaps.JIT.events.removeTopic, [removeTopicData]); - }); - this.on('noLongerPrivate', function(){ - var newTopicData = { - mappingid: this.getMapping().id, - mappableid: this.id - }; - - $(document).trigger(Metamaps.JIT.events.newTopic, [newTopicData]); - }); - - this.on('change:metacode_id', Metamaps.Filter.checkMetacodes, this); - - }, - authorizeToEdit: function (mapper) { - if (mapper && - (this.get('calculated_permission') === "commons" || - this.get('collaborator_ids').includes(mapper.get('id')) || - this.get('user_id') === mapper.get('id'))) { - return true - } else { - return false - } - }, - authorizePermissionChange: function (mapper) { - if (mapper && this.get('user_id') === mapper.get('id')) return true; - else return false; - }, - getDate: function () { - - }, - getMetacode: function () { - return Metamaps.Metacodes.get(this.get('metacode_id')); - }, - getMapping: function () { - - if (!Metamaps.Active.Map) return false; - - return Metamaps.Mappings.findWhere({ - map_id: Metamaps.Active.Map.id, - mappable_type: "Topic", - mappable_id: this.isNew() ? this.cid : this.id - }); - }, - createNode: function () { - var mapping; - var node = { - adjacencies: [], - id: this.isNew() ? this.cid : this.id, - name: this.get('name') - }; - - if (Metamaps.Active.Map) { - mapping = this.getMapping(); - node.data = { - $mapping: null, - $mappingID: mapping.id - }; - } - - return node; - }, - updateNode: function () { - var mapping; - var node = this.get('node'); - node.setData('topic', this); - - if (Metamaps.Active.Map) { - mapping = this.getMapping(); - node.setData('mapping', mapping); - } - - return node; - }, - savedEvent: function() { - Metamaps.Realtime.sendTopicChange(this); - }, - updateViews: function() { - var onPageWithTopicCard = Metamaps.Active.Map || Metamaps.Active.Topic; - var node = this.get('node'); - // update topic card, if this topic is the one open there - if (onPageWithTopicCard && this == Metamaps.TopicCard.openTopicCard) { - Metamaps.TopicCard.showCard(node); - } - - // update the node on the map - if (onPageWithTopicCard && node) { - node.name = this.get('name'); - Metamaps.Visualize.mGraph.plot(); - } - }, - updateCardView: function() { - var onPageWithTopicCard = Metamaps.Active.Map || Metamaps.Active.Topic; - var node = this.get('node'); - // update topic card, if this topic is the one open there - if (onPageWithTopicCard && this == Metamaps.TopicCard.openTopicCard) { - Metamaps.TopicCard.showCard(node); - } - }, - updateNodeView: function() { - var onPageWithTopicCard = Metamaps.Active.Map || Metamaps.Active.Topic; - var node = this.get('node'); - - // update the node on the map - if (onPageWithTopicCard && node) { - node.name = this.get('name'); - Metamaps.Visualize.mGraph.plot(); - } - } - }); - - self.TopicCollection = Backbone.Collection.extend({ - model: self.Topic, - url: '/topics' - }); - - self.Synapse = Backbone.Model.extend({ - urlRoot: '/synapses', - blacklist: ['edge', 'created_at', 'updated_at'], - toJSON: function (options) { - return _.omit(this.attributes, this.blacklist); - }, - save: function (key, val, options) { - - var attrs; - - // Handle both `"key", value` and `{key: value}` -style arguments. - if (key == null || typeof key === 'object') { - attrs = key; - options = val; - } else { - (attrs = {})[key] = val; - } - - var newOptions = options || {}; - var s = newOptions.success; - - var permBefore = this.get('permission'); - - newOptions.success = function (model, response, opt) { - if (s) s(model, response, opt); - model.trigger('saved'); - - if (permBefore === 'private' && model.get('permission') !== 'private') { - model.trigger('noLongerPrivate'); - } - else if (permBefore !== 'private' && model.get('permission') === 'private') { - model.trigger('nowPrivate'); - } - }; - return Backbone.Model.prototype.save.call(this, attrs, newOptions); - }, - initialize: function () { - if (this.isNew()) { - this.set({ - "user_id": Metamaps.Active.Mapper.id, - "permission": Metamaps.Active.Map ? Metamaps.Active.Map.get('permission') : 'commons', - "category": "from-to" - }); - } - - this.on('changeByOther', this.updateCardView); - this.on('change', this.updateEdgeView); - this.on('saved', this.savedEvent); - this.on('noLongerPrivate', function(){ - var newSynapseData = { - mappingid: this.getMapping().id, - mappableid: this.id - }; - - $(document).trigger(Metamaps.JIT.events.newSynapse, [newSynapseData]); - }); - this.on('nowPrivate', function(){ - $(document).trigger(Metamaps.JIT.events.removeSynapse, [{ - mappableid: this.id - }]); - }); - - this.on('change:desc', Metamaps.Filter.checkSynapses, this); - }, - prepareLiForFilter: function () { - var li = ''; - li += '
  • ';       - li += '
  • '; - return li; - }, - authorizeToEdit: function (mapper) { - if (mapper && (this.get('calculated_permission') === "commons" || this.get('collaborator_ids').includes(mapper.get('id')) || this.get('user_id') === mapper.get('id'))) return true; - else return false; - }, - authorizePermissionChange: function (mapper) { - if (mapper && this.get('user_id') === mapper.get('id')) return true; - else return false; - }, - getTopic1: function () { - return Metamaps.Topics.get(this.get('node1_id')); - }, - getTopic2: function () { - return Metamaps.Topics.get(this.get('node2_id')); - }, - getDirection: function () { - var t1 = this.getTopic1(), - t2 = this.getTopic2(); - - return t1 && t2 ? [ - t1.get('node').id, - t2.get('node').id - ] : false; - }, - getMapping: function () { - - if (!Metamaps.Active.Map) return false; - - return Metamaps.Mappings.findWhere({ - map_id: Metamaps.Active.Map.id, - mappable_type: "Synapse", - mappable_id: this.isNew() ? this.cid : this.id - }); - }, - createEdge: function (providedMapping) { - var mapping, mappingID; - var synapseID = this.isNew() ? this.cid : this.id; - - var edge = { - nodeFrom: this.get('node1_id'), - nodeTo: this.get('node2_id'), - data: { - $synapses: [], - $synapseIDs: [synapseID], - } - }; - - if (Metamaps.Active.Map) { - mapping = providedMapping || this.getMapping(); - mappingID = mapping.isNew() ? mapping.cid : mapping.id; - edge.data.$mappings = []; - edge.data.$mappingIDs = [mappingID]; - } - - return edge; - }, - updateEdge: function () { - var mapping; - var edge = this.get('edge'); - edge.getData('synapses').push(this); - - if (Metamaps.Active.Map) { - mapping = this.getMapping(); - edge.getData('mappings').push(mapping); - } - - return edge; - }, - savedEvent: function() { - Metamaps.Realtime.sendSynapseChange(this); - }, - updateViews: function() { - this.updateCardView(); - this.updateEdgeView(); - }, - updateCardView: function() { - var onPageWithSynapseCard = Metamaps.Active.Map || Metamaps.Active.Topic; - var edge = this.get('edge'); - - // update synapse card, if this synapse is the one open there - if (onPageWithSynapseCard && edge == Metamaps.SynapseCard.openSynapseCard) { - Metamaps.SynapseCard.showCard(edge); - } - }, - updateEdgeView: function() { - var onPageWithSynapseCard = Metamaps.Active.Map || Metamaps.Active.Topic; - var edge = this.get('edge'); - - // update the edge on the map - if (onPageWithSynapseCard && edge) { - Metamaps.Visualize.mGraph.plot(); - } - } - }); - - self.SynapseCollection = Backbone.Collection.extend({ - model: self.Synapse, - url: '/synapses' - }); - - self.Mapping = Backbone.Model.extend({ - urlRoot: '/mappings', - blacklist: ['created_at', 'updated_at'], - toJSON: function (options) { - return _.omit(this.attributes, this.blacklist); - }, - initialize: function () { - if (this.isNew()) { - this.set({ - "user_id": Metamaps.Active.Mapper.id, - "map_id": Metamaps.Active.Map ? Metamaps.Active.Map.id : null - }); - } - }, - getMap: function () { - return Metamaps.Map.get(this.get('map_id')); - }, - getTopic: function () { - if (this.get('mappable_type') === 'Topic') return Metamaps.Topic.get(this.get('mappable_id')); - else return false; - }, - getSynapse: function () { - if (this.get('mappable_type') === 'Synapse') return Metamaps.Synapse.get(this.get('mappable_id')); - else return false; - } - }); - - self.MappingCollection = Backbone.Collection.extend({ - model: self.Mapping, - url: '/mappings' - }); - - Metamaps.Metacodes = Metamaps.Metacodes ? new self.MetacodeCollection(Metamaps.Metacodes) : new self.MetacodeCollection(); - - Metamaps.Topics = Metamaps.Topics ? new self.TopicCollection(Metamaps.Topics) : new self.TopicCollection(); - - Metamaps.Synapses = Metamaps.Synapses ? new self.SynapseCollection(Metamaps.Synapses) : new self.SynapseCollection(); - - Metamaps.Mappers = Metamaps.Mappers ? new self.MapperCollection(Metamaps.Mappers) : new self.MapperCollection(); - - Metamaps.Collaborators = Metamaps.Collaborators ? new self.MapperCollection(Metamaps.Collaborators) : new self.MapperCollection(); - - // this is for topic view - Metamaps.Creators = Metamaps.Creators ? new self.MapperCollection(Metamaps.Creators) : new self.MapperCollection(); - - if (Metamaps.Active.Map) { - Metamaps.Mappings = Metamaps.Mappings ? new self.MappingCollection(Metamaps.Mappings) : new self.MappingCollection(); - - Metamaps.Active.Map = new self.Map(Metamaps.Active.Map); - } - - if (Metamaps.Active.Topic) Metamaps.Active.Topic = new self.Topic(Metamaps.Active.Topic); - - //attach collection event listeners - self.attachCollectionEvents = function () { - - Metamaps.Topics.on("add remove", function(topic){ - Metamaps.Map.InfoBox.updateNumbers(); - Metamaps.Filter.checkMetacodes(); - Metamaps.Filter.checkMappers(); - }); - - Metamaps.Synapses.on("add remove", function(synapse){ - Metamaps.Map.InfoBox.updateNumbers(); - Metamaps.Filter.checkSynapses(); - Metamaps.Filter.checkMappers(); - }); - - if (Metamaps.Active.Map) { - Metamaps.Mappings.on("add remove", function(mapping){ - Metamaps.Map.InfoBox.updateNumbers(); - Metamaps.Filter.checkSynapses(); - Metamaps.Filter.checkMetacodes(); - Metamaps.Filter.checkMappers(); - }); - } - } - self.attachCollectionEvents(); -}; // end Metamaps.Backbone.init + self.Nodes = [] + self.Edges = [] + }, + Nodes: [], + Edges: [] +}