hopglass/lib/router.js

233 lines
4.3 KiB
JavaScript
Raw Normal View History

2017-03-18 15:33:49 +01:00
define(["helper"], function (helper) {
2016-05-27 23:59:01 +02:00
"use strict";
2015-03-29 16:14:10 +02:00
return function () {
var self = this;
var objects = {nodes: {}, links: {}};
var targets = [];
var views = {};
var currentView;
var currentObject;
var running = false;
2015-03-25 20:25:41 +01:00
2015-07-07 00:06:38 +02:00
function saveState() {
var e = [];
2015-03-29 16:14:10 +02:00
if (currentView) {
e.push("v:" + currentView);
}
2015-03-29 16:14:10 +02:00
2015-07-07 00:06:38 +02:00
if (currentObject) {
if ("node" in currentObject) {
e.push("n:" + encodeURIComponent(currentObject.node.nodeinfo.node_id));
}
2015-07-07 00:06:38 +02:00
if ("link" in currentObject) {
e.push("l:" + encodeURIComponent(currentObject.link.id));
}
2015-03-29 16:14:10 +02:00
}
var s = "#!" + e.join(";");
2015-07-07 00:06:38 +02:00
window.history.pushState(s, undefined, s);
2015-03-29 16:14:10 +02:00
}
2015-03-25 20:25:41 +01:00
function resetView(push) {
2017-03-18 15:33:49 +01:00
push = helper.trueDefault(push);
2015-03-25 20:25:41 +01:00
targets.forEach(function (t) {
t.resetView();
});
2015-03-25 20:25:41 +01:00
2015-07-07 00:06:38 +02:00
if (push) {
currentObject = undefined;
saveState();
2015-07-07 00:06:38 +02:00
}
2015-03-25 20:25:41 +01:00
}
2015-03-25 20:55:49 +01:00
function gotoNode(d) {
if (!d) {
return false;
}
2015-03-31 16:30:16 +02:00
targets.forEach(function (t) {
t.gotoNode(d);
});
2015-03-31 16:30:16 +02:00
return true;
2015-03-25 20:25:41 +01:00
}
2015-03-25 20:55:49 +01:00
function gotoLink(d) {
if (!d) {
return false;
}
2015-03-31 16:30:16 +02:00
targets.forEach(function (t) {
t.gotoLink(d);
});
2015-03-31 16:30:16 +02:00
return true;
2015-03-25 20:25:41 +01:00
}
function gotoLocation(d) {
if (!d) {
return false;
}
targets.forEach(function (t) {
if (!t.gotoLocation) {
console.warn("has no gotoLocation", t);
}
t.gotoLocation(d);
});
return true;
}
2015-03-25 20:25:41 +01:00
function loadState(s) {
if (!s) {
return false;
}
2015-03-25 20:25:41 +01:00
s = decodeURIComponent(s);
if (!s.startsWith("#!")) {
return false;
}
2015-03-25 20:25:41 +01:00
var targetSet = false;
2015-03-25 20:25:41 +01:00
2015-07-07 00:06:38 +02:00
s.slice(2).split(";").forEach(function (d) {
var args = d.split(":");
2015-03-25 20:25:41 +01:00
2015-07-07 00:06:38 +02:00
if (args[0] === "v" && args[1] in views) {
currentView = args[1];
views[args[1]]();
2015-03-27 22:25:28 +01:00
}
2015-03-25 20:25:41 +01:00
var id;
2015-07-07 00:06:38 +02:00
if (args[0] === "n") {
id = args[1];
2015-07-07 00:06:38 +02:00
if (id in objects.nodes) {
currentObject = {node: objects.nodes[id]};
gotoNode(objects.nodes[id]);
targetSet = true;
2015-07-07 00:06:38 +02:00
}
2015-03-27 22:25:28 +01:00
}
2015-07-07 00:06:38 +02:00
if (args[0] === "l") {
id = args[1];
2015-07-07 00:06:38 +02:00
if (id in objects.links) {
currentObject = {link: objects.links[id]};
gotoLink(objects.links[id]);
targetSet = true;
2015-07-07 00:06:38 +02:00
}
}
});
2015-07-07 00:06:38 +02:00
return targetSet;
2015-03-27 22:25:28 +01:00
}
self.start = function () {
running = true;
if (!loadState(window.location.hash)) {
resetView(false);
}
2015-03-27 22:25:28 +01:00
window.onpopstate = function (d) {
if (!loadState(d.state)) {
resetView(false);
}
};
};
2015-03-25 20:25:41 +01:00
2015-07-07 00:06:38 +02:00
self.view = function (d) {
if (d in views) {
views[d]();
2015-07-07 00:06:38 +02:00
if (!currentView || running) {
currentView = d;
}
2015-07-07 00:10:42 +02:00
if (!running) {
return;
}
2015-07-07 00:30:35 +02:00
saveState();
2015-07-07 00:30:35 +02:00
if (!currentObject) {
resetView(false);
return;
2015-07-07 00:06:38 +02:00
}
2015-07-07 00:30:35 +02:00
if ("node" in currentObject) {
gotoNode(currentObject.node);
}
2015-07-07 00:30:35 +02:00
if ("link" in currentObject) {
gotoLink(currentObject.link);
}
2015-07-07 00:06:38 +02:00
}
};
2015-07-07 00:06:38 +02:00
2015-03-25 20:55:49 +01:00
self.node = function (d) {
return function () {
2015-07-07 00:06:38 +02:00
if (gotoNode(d)) {
currentObject = {node: d};
saveState();
2015-07-07 00:06:38 +02:00
}
2015-03-31 16:30:16 +02:00
return false;
};
};
2015-03-25 20:55:49 +01:00
self.link = function (d) {
return function () {
2015-07-07 00:06:38 +02:00
if (gotoLink(d)) {
currentObject = {link: d};
saveState();
2015-07-07 00:06:38 +02:00
}
2015-03-31 16:30:16 +02:00
return false;
};
};
2015-03-25 20:55:49 +01:00
self.gotoLocation = gotoLocation;
2015-03-25 20:55:49 +01:00
self.reset = function () {
resetView();
};
2015-03-25 20:55:49 +01:00
2015-03-31 22:18:09 +02:00
self.addTarget = function (d) {
targets.push(d);
};
2015-03-31 22:18:09 +02:00
self.removeTarget = function (d) {
targets = targets.filter(function (e) {
return d !== e;
});
};
2015-03-25 20:25:41 +01:00
2015-07-07 00:06:38 +02:00
self.addView = function (k, d) {
views[k] = d;
};
2015-07-07 00:06:38 +02:00
2015-03-29 17:48:25 +02:00
self.setData = function (data) {
objects.nodes = {};
objects.links = {};
2015-03-25 20:25:41 +01:00
data.nodes.all.forEach(function (d) {
objects.nodes[d.nodeinfo.node_id] = d;
});
2015-03-25 20:25:41 +01:00
data.graph.links.forEach(function (d) {
objects.links[d.id] = d;
});
};
2015-03-25 20:25:41 +01:00
return self;
};
});