hedera-web/js/vn/hash.js

165 lines
3.0 KiB
JavaScript

var VnDate = require('./date');
var Lot = require('./lot');
/**
* Class to handle the hash part of the URL as a key-value javascript object.
* It also handles dates and objects as a value.
*/
module.exports = new Class({
Extends: Lot
,Properties: {
/**
* The main window object.
*/
window:
{
type: Window
,set(x) {
this._window = x;
x.addEventListener('hashchange', this._hashChangedHandler);
this._hashChanged();
}
,get() {
return this._window;
}
}
}
,initialize(props) {
Object.assign(this, {
_hash: null
,_hashLock: false
,_window: null
,_hashChangedHandler: this._hashChanged.bind(this)
});
Lot.prototype.initialize.call(this, props);
}
,_paramsChanged() {
this.updateHash();
}
/**
* Creates a URL with the given hash data.
*
* @param {Object} params A key-value object
* @param {boolean} add %true to combine with the current params, %false otherwise
* @return {string} The URL
*/
,make(params, add) {
if (add) {
params = Object.assign({}, params);
for (var key in this._params)
if (!params[key])
params[key] = this._params[key];
}
return this.renderHash(params);
}
/**
* Updates the window hash with current params.
*/
,updateHash() {
if (this._hashLock)
return;
this._hash = this.renderHash(this._params);
this._hashLock = true;
location.hash = this._hash;
this._hashLock = false;
}
/*
* Called when window hash changes.
*/
,_hashChanged() {
var newHash = location.hash;
if (this._hashLock || this._hash === newHash)
return;
this._hash = newHash;
this._hashLock = true;
this.params = this.parseHash(newHash);
this._hashLock = false;
}
/**
* Creates a URL with the given hash data.
*
* @param {Object} params The key-value object
* @return {string} The URL
*/
,renderHash(params) {
var hash = '#!';
for (var key in params)
if (params[key] !== undefined) {
if (hash.length > 2)
hash += '&';
hash += encodeURIComponent(key) +'='+ this.renderValue(params[key]);
}
return hash;
}
/**
* Parses a hash string to a key-value object.
*
* @param {string} hashString The hash string
* @return {Object} The key-value object
*/
,parseHash(hashString) {
var newMap = hashMap = {};
var kvPairs = hashString.substr(2).split('&');
for (var i = 0; i < kvPairs.length; i++) {
var kvPair = kvPairs[i].split('=', 2);
if (kvPair[0])
newMap[decodeURIComponent(kvPair[0])] = this.parseValue(kvPair[1]);
}
return newMap;
}
,renderValue(v) {
if (v == null)
return '';
switch (typeof v) {
case 'object':
if (v instanceof Date)
return VnDate.strftime(v, '%Y-%m-%d');
else
return JSON.stringify(v)
}
return v;
}
,parseValue(v) {
if (v == null)
return v;
v = decodeURIComponent(v);
if (v === '')
return null;
return v;
}
,_destroy() {
this._window.removeEventListener('hashchange', this._hashChangedHandler);
this._window = null;
Lot.prototype._destroy.call(this);
}
});