| /* |
| * Copyright 2016-present Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* |
| ONOS GUI -- Topology Force Module. |
| Visualization of the topology in an SVG layer, using a D3 Force Layout. |
| */ |
| |
| (function () { |
| 'use strict'; |
| |
| function Model(attributes) { |
| |
| var attrs = attributes || {}; |
| this.attributes = {}; |
| |
| attrs = angular.extend({}, attrs); |
| this.set(attrs, { silent: true }); |
| this.initialize.apply(this, arguments); |
| } |
| |
| Model.prototype = { |
| |
| initialize: function () {}, |
| |
| onChange: function (property, value, options) {}, |
| |
| get: function (attr) { |
| return this.attributes[attr]; |
| }, |
| |
| set: function (key, val, options) { |
| |
| if (!key) { |
| return this; |
| } |
| |
| var attributes; |
| if (typeof key === 'object') { |
| attributes = key; |
| options = val; |
| } else { |
| (attributes = {})[key] = val; |
| } |
| |
| var opts = options || (options = {}); |
| |
| var unset = opts.unset, |
| silent = opts.silent, |
| changes = [], |
| changing = this._changing; |
| |
| this._changing = true; |
| |
| if (!changing) { |
| |
| // NOTE: angular.copy causes issues in chrome |
| this._previousAttributes = Object.create( |
| Object.getPrototypeOf(this.attributes) |
| ); |
| this.changed = {}; |
| } |
| |
| var current = this.attributes, |
| changed = this.changed, |
| previous = this._previousAttributes; |
| |
| angular.forEach(attributes, function (attribute, index) { |
| |
| val = attribute; |
| |
| if (!angular.equals(current[index], val)) { |
| changes.push(index); |
| } |
| |
| if (angular.equals(previous[index], val)) { |
| delete changed[index]; |
| } else { |
| changed[index] = val; |
| } |
| |
| if (unset) { |
| delete current[index]; |
| } else { |
| current[index] = val; |
| } |
| }); |
| |
| // Trigger all relevant attribute changes. |
| if (!silent) { |
| if (changes.length) { |
| this._pending = opts; |
| } |
| for (var i = 0; i < changes.length; i++) { |
| this.onChange(changes[i], this, |
| current[changes[i]], opts); |
| } |
| } |
| |
| this._changing = false; |
| return this; |
| }, |
| toJSON: function (options) { |
| return angular.copy(this.attributes); |
| } |
| }; |
| |
| angular.module('ovTopo2') |
| .factory('Topo2Model', [ |
| 'FnService', |
| function (fn) { |
| Model.extend = fn.extend; |
| |
| return Model; |
| } |
| ]); |
| })(); |