|
82 | 82 | } |
83 | 83 |
|
84 | 84 | var nodes = find('.tree-node', tree); |
85 | | - nodes[0].classList.add('active'); |
| 85 | + var hashHistory = []; |
86 | 86 |
|
| 87 | + // Pull tree history from hash |
| 88 | + function updateHashHistory() { |
| 89 | + hashHistory = window.location.hash.replace('#','').split('!'); |
| 90 | + if (hashHistory.length == 1) { |
| 91 | + hashHistory = ["tree-node-start"]; |
| 92 | + } |
| 93 | + } |
| 94 | + |
| 95 | + // Update tree to reflect hash state |
| 96 | + function renderTree() { |
| 97 | + updateHashHistory(); |
| 98 | + var treeNodes = nodes.filter(function(n) { |
| 99 | + return n.classList && n.classList.contains('tree-node'); |
| 100 | + }); |
| 101 | + for (var i = 0; i < treeNodes.length; i++) { |
| 102 | + var node = treeNodes[i]; |
| 103 | + if (hashHistory.includes(node.getAttribute('id'))) { |
| 104 | + node.classList.add('active'); |
| 105 | + } else { |
| 106 | + node.classList.remove('active'); |
| 107 | + } |
| 108 | + var childNodes = Array.prototype.concat.apply([], node.childNodes); |
| 109 | + var childNode = childNodes.filter(function(n) { |
| 110 | + return n.classList && n.classList.contains('tree-node-options'); |
| 111 | + })[0]; |
| 112 | + if (!childNode) { |
| 113 | + continue; |
| 114 | + } |
| 115 | + if (hashHistory[hashHistory.length - 1] == node.getAttribute('id')) { |
| 116 | + childNode.classList.remove('hidden'); |
| 117 | + } else { |
| 118 | + childNode.classList.add('hidden'); |
| 119 | + } |
| 120 | + } |
| 121 | + if (hashHistory.length > 1) { |
| 122 | + var node = document.getElementById(hashHistory[hashHistory.length - 1]); |
| 123 | + node.scrollIntoView({ |
| 124 | + behavior: "smooth" |
| 125 | + }); |
| 126 | + } |
| 127 | + } |
| 128 | + |
| 129 | + // Render tree as it is now |
| 130 | + renderTree(); |
| 131 | + |
| 132 | + // Re-render tree each time the hash changes |
| 133 | + window.addEventListener("hashchange", function() { |
| 134 | + renderTree(); |
| 135 | + }); |
| 136 | + |
| 137 | + // Update hash each time the tree is clicked |
87 | 138 | tree.addEventListener('click', function treeNodeButtonClick(e) { |
88 | 139 | if (!e.target.classList.contains('tree-link')) { |
89 | 140 | return; |
90 | 141 | } |
91 | | - |
92 | 142 | e.preventDefault(); |
93 | | - |
94 | 143 | var node = nodes.filter(function(n) { |
95 | 144 | return n.getAttribute('id') === e.target.getAttribute('href').substr(1); |
96 | 145 | })[0]; |
97 | 146 | if (node) { |
98 | | - node.classList.add('active'); |
99 | | - node.scrollIntoView({ |
100 | | - behavior: "smooth" |
101 | | - }); |
102 | | - var answer = document.createElement('p'); |
103 | | - answer.classList.add('tree-node-answer'); |
104 | | - answer.innerText = e.target.innerText; |
105 | | - e.target.parentNode.parentNode.appendChild(answer); |
106 | | - e.target.parentNode.classList.add('hidden'); |
| 147 | + hashHistory.push(node.getAttribute('id')); |
| 148 | + window.location.hash = hashHistory.join("!"); |
107 | 149 | } |
108 | 150 | }); |
109 | 151 |
|
| 152 | + // support reset |
110 | 153 | tree.querySelector('a.tree-reset').addEventListener('click', function treeNodeButtonClick(e) { |
111 | 154 | e.preventDefault(); |
112 | | - nodes.forEach(function(n, i) { |
113 | | - if (i === 0) { |
114 | | - return; |
115 | | - } |
116 | | - n.classList.remove('active'); |
117 | | - }); |
118 | | - find('.tree-node-options', tree).forEach(function(n) { |
119 | | - n.classList.remove('hidden'); |
120 | | - }); |
121 | | - find('.tree-node-answer', tree).forEach(function(n) { |
122 | | - n.parentNode.removeChild(n); |
123 | | - }); |
| 155 | + window.location.hash = ""; |
124 | 156 | }); |
125 | 157 | })(); |
126 | | - |
127 | 158 | })(); |
0 commit comments