diff options
Diffstat (limited to 'ofborg/ofborg-viewer/src/state.js')
| -rw-r--r-- | ofborg/ofborg-viewer/src/state.js | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/ofborg/ofborg-viewer/src/state.js b/ofborg/ofborg-viewer/src/state.js new file mode 100644 index 0000000000..936d07653a --- /dev/null +++ b/ofborg/ofborg-viewer/src/state.js @@ -0,0 +1,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; |
