diff --git a/lib/main.js b/lib/main.js index 7cc6b1f..818def8 100644 --- a/lib/main.js +++ b/lib/main.js @@ -1,5 +1,5 @@ -require(["map", "sidebar", "meshstats", "linklist", "simplenodelist", "infobox/main"], -function (Map, Sidebar, Meshstats, Linklist, SimpleNodelist, Infobox) { +require(["router", "map", "sidebar", "meshstats", "linklist", "simplenodelist", "infobox/main"], +function (Router, Map, Sidebar, Meshstats, Linklist, SimpleNodelist, Infobox) { main() function main() { @@ -37,6 +37,7 @@ function (Map, Sidebar, Meshstats, Linklist, SimpleNodelist, Infobox) { var p = Promise.all(urls.map(getJSON)) p.then(handle_data(sidebar, meshstats, linklist, newnodeslist, lostnodeslist, infobox, map, router)) + .then(function () { router.loadState(window.location.hash) }) }) } @@ -111,117 +112,7 @@ function (Map, Sidebar, Meshstats, Linklist, SimpleNodelist, Infobox) { linklist.setData(links) newnodeslist.setData(newnodes) lostnodeslist.setData(lostnodes) - - var historyDict = { nodes: {}, links: {} } - - nodes.forEach( function (d) { - historyDict.nodes[d.nodeinfo.node_id] = d - }) - - links.forEach( function (d) { - historyDict.links[linkId(d)] = d - }) - - router.reset(false) - - gotoHistory(router, historyDict, window.location.hash) - - window.onpopstate = function (d) { - gotoHistory(router, historyDict, d.state) - } + router.setData(nodes, links) } } - - function pushHistory(d) { - var s = "#!" - - if (d) { - if ("node" in d) - s += "n:" + d.node.nodeinfo.node_id - - if ("link" in d) - s += "l:" + linkId(d.link) - } - - window.history.pushState(s, undefined, s) - } - - function gotoHistory(router, dict, s) { - if (!s.startsWith("#!")) - return - - s = s.slice(2) - - var args = s.split(":") - - if (args[0] === "n") { - var id = args[1] - - if (id in dict.nodes) - router.node(dict.nodes[id], true, false)() - } - - if (args[0] === "l") { - var id = args[1] - - if (id in dict.links) - router.link(dict.links[id], true, false)() - } - } - - function Router(config, nodes) { - var targets = [] - var self = this - - var infobox - - function resetView(push) { - push = trueDefault(push) - - targets.forEach( function (t) { - t.resetView() - }) - - if (push) - pushHistory() - } - - function gotoNode(d, showMap, push) { - showMap = trueDefault(showMap) - push = trueDefault(push) - - targets.forEach( function (t) { - t.gotoNode(d) - }) - - if (push) - pushHistory( { node: d }) - - return false - } - - function gotoLink(d, showMap, push) { - showMap = trueDefault(showMap) - push = trueDefault(push) - - targets.forEach( function (t) { - t.gotoLink(d) - }) - - if (push) - pushHistory( { link: d }) - - return false - } - - self.node = function (d, m, p) { return function () { return gotoNode(d, m, p) }} - self.link = function (d, m, p) { return function () { return gotoLink(d, m, p) }} - self.reset = resetView - self.addMarkers = function (d) { - markers = d - } - self.addTarget = function (d) { targets.push(d) } - - return self - } }) diff --git a/lib/router.js b/lib/router.js new file mode 100644 index 0000000..4b1d74d --- /dev/null +++ b/lib/router.js @@ -0,0 +1,112 @@ +define(function () { + return function (config) { + var objects = { nodes: {}, links: {} } + var targets = [] + var self = this + + function resetView(push) { + push = trueDefault(push) + + targets.forEach( function (t) { + t.resetView() + }) + + if (push) + saveState() + } + + function gotoNode(d, showMap, push) { + showMap = trueDefault(showMap) + push = trueDefault(push) + + targets.forEach( function (t) { + t.gotoNode(d) + }) + + if (push) + saveState( { node: d }) + + return false + } + + function gotoLink(d, showMap, push) { + showMap = trueDefault(showMap) + push = trueDefault(push) + + targets.forEach( function (t) { + t.gotoLink(d) + }) + + if (push) + saveState( { link: d }) + + return false + } + + function saveState(d) { + var s = "#!" + + if (d) { + if ("node" in d) + s += "n:" + d.node.nodeinfo.node_id + + if ("link" in d) + s += "l:" + linkId(d.link) + } + + window.history.pushState(s, undefined, s) + } + + function loadState(s) { + if (!s) + return + + if (!s.startsWith("#!")) + return + + var args = s.slice(2).split(":") + + if (args.length == 1 && args[0] == "") + resetView(false) + + if (args[0] === "n") { + var id = args[1] + + if (id in objects.nodes) + gotoNode(objects.nodes[id], true, false) + } + + if (args[0] === "l") { + var id = args[1] + + if (id in objects.links) + gotoLink(objects.links[id], true, false) + } + } + + self.node = function (d, m, p) { return function () { return gotoNode(d, m, p) }} + self.link = function (d, m, p) { return function () { return gotoLink(d, m, p) }} + self.reset = resetView + self.addMarkers = function (d) { + markers = d + } + self.addTarget = function (d) { targets.push(d) } + + self.setData = function (nodes, links) { + objects.nodes = {} + objects.links = {} + + nodes.forEach( function (d) { + objects.nodes[d.nodeinfo.node_id] = d + }) + + links.forEach( function (d) { + objects.links[linkId(d)] = d + }) + } + + window.onpopstate = function (d) { loadState(d.state) } + + return self + } +})