// select.js — which nodes and edges are selected. // // Kept apart from the document so selection never lands in the undo stack or // on disk: undoing an edit should restore geometry, not re-select whatever // happened to be highlighted at the time. window.Canvas = window.Canvas || {}; Canvas.Select = (function () { var nodes = {}; var edges = {}; var listeners = []; function emit() { for (var i = 0; i < listeners.length; i++) listeners[i](); } function keys(obj) { return Object.keys(obj); } return { nodes: function () { return keys(nodes); }, edges: function () { return keys(edges); }, hasNode: function (id) { return !!nodes[id]; }, hasEdge: function (id) { return !!edges[id]; }, isEmpty: function () { return !keys(nodes).length && !keys(edges).length; }, count: function () { return keys(nodes).length + keys(edges).length; }, set: function (nodeIds, edgeIds) { nodes = {}; edges = {}; (nodeIds || []).forEach(function (id) { nodes[id] = true; }); (edgeIds || []).forEach(function (id) { edges[id] = true; }); emit(); }, addNode: function (id) { if (nodes[id]) return; nodes[id] = true; emit(); }, toggleNode: function (id) { if (nodes[id]) delete nodes[id]; else nodes[id] = true; emit(); }, toggleEdge: function (id) { if (edges[id]) delete edges[id]; else edges[id] = true; emit(); }, clear: function () { if (!keys(nodes).length && !keys(edges).length) return; nodes = {}; edges = {}; emit(); }, // prune drops ids that no longer exist. Called after undo/redo, where // the document can lose nodes the selection still refers to. prune: function (doc) { var changed = false; var live = {}; doc.nodes.forEach(function (n) { live[n.id] = true; }); keys(nodes).forEach(function (id) { if (!live[id]) { delete nodes[id]; changed = true; } }); var liveEdges = {}; doc.edges.forEach(function (e) { liveEdges[e.id] = true; }); keys(edges).forEach(function (id) { if (!liveEdges[id]) { delete edges[id]; changed = true; } }); if (changed) emit(); }, onChange: function (fn) { listeners.push(fn); } }; })();