summaryrefslogtreecommitdiff
path: root/ofborg/ofborg-viewer/src/state.js
blob: 936d07653a874feba3c6580af081d1a51f670efa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import queryString from "query-string";
import isEqual from "lodash/isEqual";

/**
 * Maps the state of the application to the history API.
 * This is used to make the current view linkable.
 * In the URL, the hash part is **reserved for line numbers**.
 * (line number links are not implemented yet.)
 */
class State {

	/**
	 * Loads the state from URL.
	 *
	 * Prepares event listeners.
	 */
	constructor() {
		const params = queryString.parse(location.search);
		const {history} = window;
		// Loads from params in URL, then history in order of importance.
		this.params = Object.assign({}, params, history.state);

		window.onpopstate = (e) => this.handle_popstate(e);
	}

	handle_popstate(e) {
		console.log(e);
		const {state} = e;
		if (state) {
			this.set_state(state, {push: false});
			if (this.on_state_change) {
				this.on_state_change(state);
			}
		}
	}

	set_state(new_state, {push} = {push: true}) {
		const {history} = window;
		const params = Object.assign({}, this.params, new_state);
		Object.keys(params).forEach((k) => {
			if (!params[k]) {
				Reflect.deleteProperty(params, k);
			}
		});

		if (isEqual(params, this.params)) {
			// set_state won't fire on "identity" change.
			return;
		}

		this.params = params;

		if (push) {
			history.pushState(this.params, "", `?${queryString.stringify(params)}`);
		}
	}
}

export default State;