diff --git a/calc.html b/calc.html
index 8e396c9a..8434b28b 100644
--- a/calc.html
+++ b/calc.html
@@ -62,13 +62,13 @@
-
+
-
-
-
-
-
+
+
+
+
+
diff --git a/display.js b/display.js
index fa7a6890..45e78e1b 100644
--- a/display.js
+++ b/display.js
@@ -900,9 +900,9 @@ function display() {
}
var totals = globalTotals
- window.location.hash = "#" + formatSettings()
+ updateHash()
- if (currentTab == "graph_tab") {
+ if (currentTab == "graph") {
renderGraph(totals, spec.ignore)
}
recipeTable.displaySolution(totals)
diff --git a/events.js b/events.js
index 4d391ef8..e456bc59 100644
--- a/events.js
+++ b/events.js
@@ -1,5 +1,33 @@
"use strict"
+// correctly handle back/forward buttons
+
+var plannedHashUpdate = false
+var navigationInProgress = false
+document.addEventListener("DOMContentLoaded", function() {
+ window.addEventListener("hashchange", function() {
+ if (plannedHashUpdate) {
+ // reset flag for next hashChange
+ plannedHashUpdate = false
+ return
+ }
+ navigationInProgress = true
+ var settings = loadSettings(window.location.hash)
+ if ("data" in settings && settings.data != currentMod()) {
+ document.getElementById("data_set").value = settings.data
+ changeMod(settings)
+ } else {
+ // changeMod >> loadData also does all this so don't repeat it
+ renderSettings(settings)
+ loadModules(settings)
+ loadItems(settings)
+ itemUpdate()
+ }
+ clickTab(settings.tab)
+ navigationInProgress = false
+ });
+});
+
// build target events
// The "+" button to add a new target.
@@ -48,11 +76,11 @@ function RateHandler(target) {
// Obtains current data set from UI element, and resets the world with the new
// data.
-function changeMod() {
+function changeMod(settings) {
var modName = currentMod()
reset()
- loadData(modName)
+ loadData(modName, settings)
}
// Triggered when the display rate is changed.
@@ -306,22 +334,28 @@ function GraphClickHandler(node) {
// tab events
-var DEFAULT_TAB = "totals_tab"
+var DEFAULT_TAB = "totals"
-var currentTab = DEFAULT_TAB
+var currentTab
var tabMap = {
- "totals_tab": "totals_button",
- "steps_tab": "steps_button",
- "graph_tab": "graph_button",
- "settings_tab": "settings_button",
- "about_tab": "about_button",
- "faq_tab": "faq_button",
- "debug_tab": "debug_button",
+ "totals": "totals_button",
+ "steps": "steps_button",
+ "graph": "graph_button",
+ "settings": "settings_button",
+ "about": "about_button",
+ "faq": "faq_button",
+ "debug": "debug_button",
}
// Triggered when a tab is clicked on.
function clickTab(tabName) {
+ if (!tabName) {
+ tabName = DEFAULT_TAB
+ }
+ if (tabName == currentTab) {
+ return
+ }
currentTab = tabName
var tabs = document.getElementsByClassName("tab")
for (var i=0; i < tabs.length; i++) {
@@ -332,18 +366,15 @@ function clickTab(tabName) {
for (var i=0; i < buttons.length; i++) {
buttons[i].classList.remove("active")
}
-
- document.getElementById(tabName).style.display = "block"
+ document.getElementById(tabName + "_tab").style.display = "block"
var button = document.getElementById(tabMap[tabName])
button.classList.add("active")
- if (initDone) {
- window.location.hash = "#" + formatSettings()
- }
+ updateHash()
}
// Triggered when the "Visualize" tab is clicked on.
-function clickVisualize(event, tabName) {
- clickTab(event, tabName)
+function clickVisualize(tabName) {
+ clickTab(tabName)
renderGraph(globalTotals, spec.ignore)
}
@@ -357,4 +388,3 @@ function toggleVisible(targetID) {
target.style.display = "none"
}
}
-
diff --git a/fragment.js b/fragment.js
index 0ad1a4a4..339c38fb 100644
--- a/fragment.js
+++ b/fragment.js
@@ -1,9 +1,13 @@
"use strict"
-function formatSettings() {
+function updateHash() {
+ if (navigationInProgress) {
+ return
+ }
+
var settings = ""
if (currentTab != DEFAULT_TAB) {
- settings += "tab=" + currentTab.slice(0, currentTab.indexOf("_")) + "&"
+ settings += "tab=" + currentTab + "&"
}
var mod = currentMod()
if (mod != DEFAULT_MODIFICATION) {
@@ -110,9 +114,13 @@ function formatSettings() {
}
var zip = "zip=" + window.btoa(pako.deflateRaw(settings, {to: "string"}))
if (zip.length < settings.length) {
- return zip
+ settings = zip
+ }
+ settings = "#" + settings
+ if (window.location.hash != settings) {
+ plannedHashUpdate = true;
+ window.location.hash = settings
}
- return settings
}
function loadSettings(fragment) {
diff --git a/init.js b/init.js
index 3043c543..117ab80c 100644
--- a/init.js
+++ b/init.js
@@ -18,8 +18,6 @@ var shortModules
// Array of item groups, in turn divided into subgroups. For display purposes.
var itemGroups
-var initDone = false
-
// Set the page back to a state immediately following initial setup, but before
// the dataset is loaded for the first time.
//
@@ -48,6 +46,80 @@ function reset() {
oldTotals.parentNode.replaceChild(newTotals, oldTotals)
}
+function loadItems(settings) {
+ // clear current targets
+ build_targets = []
+ var targetList = document.getElementById("targets")
+ targetList.innerHTML = targetList.lastChild.outerHTML
+
+ if ("items" in settings && settings.items != "") {
+ var targets = settings.items.split(",")
+ for (var i=0; i < targets.length; i++) {
+ var targetString = targets[i]
+ var parts = targetString.split(":")
+ var name = parts[0]
+ var target = addTarget(name)
+ var type = parts[1]
+ if (type == "f") {
+ target.setFactories(parts[2])
+ } else if (type == "r") {
+ target.setRate(parts[2])
+ } else {
+ throw new Error("unknown target type")
+ }
+ }
+ } else {
+ addTarget()
+ }
+}
+
+function loadModules(settings) {
+ if ("modules" in settings && settings.modules != "") {
+ var moduleSettings = settings.modules.split(",")
+ for (var i=0; i < moduleSettings.length; i++) {
+ var bothSettings = moduleSettings[i].split(";")
+ var factoryModuleSettings = bothSettings[0]
+ var beaconSettings = bothSettings[1]
+
+ var singleModuleSettings = factoryModuleSettings.split(":")
+ var recipeName = singleModuleSettings[0]
+ var recipe = solver.recipes[recipeName]
+ var moduleNameList = singleModuleSettings.slice(1)
+ for (var j=0; j < moduleNameList.length; j++) {
+ var moduleName = moduleNameList[j]
+ if (moduleName && moduleName != "null") {
+ var module
+ if (moduleName in modules) {
+ module = modules[moduleName]
+ } else if (moduleName in shortModules) {
+ module = shortModules[moduleName]
+ }
+ if (module) {
+ spec.setModule(recipe, j, module)
+ }
+ }
+ }
+ if (beaconSettings) {
+ beaconSettings = beaconSettings.split(":")
+ var moduleName = beaconSettings[0]
+ var module = null
+ if (moduleName in modules) {
+ module = modules[moduleName]
+ } else if (moduleName in shortModules) {
+ module = shortModules[moduleName]
+ }
+ var factory = spec.getFactory(recipe)
+ var count = RationalFromFloat(Number(beaconSettings[1]))
+ if (module === spec.defaultBeacon) {
+ module = null
+ }
+ factory.beaconModule = module
+ factory.beaconCount = count
+ }
+ }
+ }
+}
+
function loadDataRunner(modName, callback) {
var xobj = new XMLHttpRequest()
var mod = MODIFICATIONS[modName]
@@ -96,71 +168,9 @@ function loadData(modName, settings) {
solver = new Solver(items, recipes)
renderSettings(settings)
-
- if ("items" in settings && settings.items != "") {
- var targets = settings.items.split(",")
- for (var i=0; i < targets.length; i++) {
- var targetString = targets[i]
- var parts = targetString.split(":")
- var name = parts[0]
- var target = addTarget(name)
- var type = parts[1]
- if (type == "f") {
- target.setFactories(parts[2])
- } else if (type == "r") {
- target.setRate(parts[2])
- } else {
- throw new Error("unknown target type")
- }
- }
- } else {
- addTarget()
- }
- if ("modules" in settings && settings.modules != "") {
- var moduleSettings = settings.modules.split(",")
- for (var i=0; i < moduleSettings.length; i++) {
- var bothSettings = moduleSettings[i].split(";")
- var factoryModuleSettings = bothSettings[0]
- var beaconSettings = bothSettings[1]
-
- var singleModuleSettings = factoryModuleSettings.split(":")
- var recipeName = singleModuleSettings[0]
- var recipe = recipes[recipeName]
- var moduleNameList = singleModuleSettings.slice(1)
- for (var j=0; j < moduleNameList.length; j++) {
- var moduleName = moduleNameList[j]
- if (moduleName && moduleName != "null") {
- var module
- if (moduleName in modules) {
- module = modules[moduleName]
- } else if (moduleName in shortModules) {
- module = shortModules[moduleName]
- }
- if (module) {
- spec.setModule(recipe, j, module)
- }
- }
- }
- if (beaconSettings) {
- beaconSettings = beaconSettings.split(":")
- var moduleName = beaconSettings[0]
- var module = null
- if (moduleName in modules) {
- module = modules[moduleName]
- } else if (moduleName in shortModules) {
- module = shortModules[moduleName]
- }
- var factory = spec.getFactory(recipe)
- var count = RationalFromFloat(Number(beaconSettings[1]))
- if (module === spec.defaultBeacon) {
- module = null
- }
- factory.beaconModule = module
- factory.beaconCount = count
- }
- }
- }
- initDone = true
+ loadModules(settings)
+ loadItems(settings)
+ clickTab(settings.tab)
itemUpdate()
})
}
@@ -168,11 +178,5 @@ function loadData(modName, settings) {
function init() {
var settings = loadSettings(window.location.hash)
renderDataSetOptions(settings)
- if ("tab" in settings) {
- currentTab = settings.tab + "_tab"
- }
loadData(currentMod(), settings)
- // We don't need to call clickVisualize here, as we will properly render
- // the graph when we call itemUpdate() at the end of initialization.
- clickTab(currentTab)
}