2020-08-12 06:25:36 +08:00
|
|
|
/*!!
|
|
|
|
* Hasher <http://github.com/millermedeiros/hasher>
|
|
|
|
* @author Miller Medeiros
|
|
|
|
* @version 1.1.2 (2012/10/31 03:19 PM)
|
|
|
|
* Released under the MIT License
|
|
|
|
*/
|
|
|
|
|
|
|
|
(global => {
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
2021-02-04 19:54:03 +08:00
|
|
|
// Private
|
2020-08-12 06:25:36 +08:00
|
|
|
//--------------------------------------------------------------------------------------
|
|
|
|
|
2021-02-04 19:54:03 +08:00
|
|
|
const
|
|
|
|
_hashValRegexp = /#(.*)$/,
|
2022-03-03 23:28:05 +08:00
|
|
|
_hashRegexp = /^[#/]+/,
|
2022-10-05 17:05:04 +08:00
|
|
|
_hashTrim = /^\/+/g,
|
2022-09-13 04:07:51 +08:00
|
|
|
_trimHash = hash => hash?.replace(_hashTrim, '') || '',
|
2020-08-12 06:25:36 +08:00
|
|
|
_getWindowHash = () => {
|
|
|
|
//parsed full URL instead of getting window.location.hash because Firefox decode hash value (and all the other browsers don't)
|
2021-02-04 19:54:03 +08:00
|
|
|
var result = _hashValRegexp.exec( location.href );
|
2022-09-13 04:07:51 +08:00
|
|
|
return result?.[1] ? decodeURIComponent(result[1]) : '';
|
2020-08-12 06:25:36 +08:00
|
|
|
},
|
|
|
|
_registerChange = newHash => {
|
2021-02-04 19:54:03 +08:00
|
|
|
if (_hash !== newHash) {
|
2020-08-12 06:25:36 +08:00
|
|
|
var oldHash = _hash;
|
|
|
|
_hash = newHash; //should come before event dispatch to make sure user can get proper value inside event handler
|
2022-03-03 23:28:05 +08:00
|
|
|
_dispatch(_trimHash(newHash), _trimHash(oldHash));
|
2020-08-12 06:25:36 +08:00
|
|
|
}
|
|
|
|
},
|
2021-02-04 19:54:03 +08:00
|
|
|
_setHash = (path, replace) => {
|
|
|
|
path = path ? '/' + path.replace(_hashRegexp, '') : path;
|
|
|
|
if (path !== _hash){
|
|
|
|
// we should store raw value
|
|
|
|
_registerChange(path);
|
|
|
|
if (path === _hash) {
|
2021-11-01 18:24:11 +08:00
|
|
|
path = '#' + encodeURI(path)
|
2021-02-04 19:54:03 +08:00
|
|
|
// we check if path is still === _hash to avoid error in
|
|
|
|
// case of multiple consecutive redirects [issue #39]
|
|
|
|
replace
|
2021-11-01 18:24:11 +08:00
|
|
|
? location.replace(path)
|
|
|
|
: (location.hash = path);
|
2021-02-04 19:54:03 +08:00
|
|
|
}
|
|
|
|
}
|
2020-08-12 06:25:36 +08:00
|
|
|
},
|
2022-03-03 23:28:05 +08:00
|
|
|
_dispatch = (...args) => hasher.active && _bindings.forEach(callback => callback(...args)),
|
2020-08-12 06:25:36 +08:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
|
|
// Public (API)
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
hasher = /** @lends hasher */ {
|
2021-11-01 18:24:11 +08:00
|
|
|
clear : () => {
|
|
|
|
_bindings = [];
|
|
|
|
hasher.active = true;
|
|
|
|
},
|
2020-08-12 06:25:36 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Signal dispatched when hash value changes.
|
|
|
|
* - pass current hash as 1st parameter to listeners and previous hash value as 2nd parameter.
|
|
|
|
* @type signals.Signal
|
|
|
|
*/
|
2021-08-13 16:01:01 +08:00
|
|
|
active : true,
|
|
|
|
add : callback => _bindings.push(callback),
|
2020-08-12 06:25:36 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Start listening/dispatching changes in the hash/history.
|
|
|
|
* <ul>
|
|
|
|
* <li>hasher won't dispatch CHANGE events by manually typing a new value or pressing the back/forward buttons before calling this method.</li>
|
|
|
|
* </ul>
|
|
|
|
*/
|
2022-03-03 23:28:05 +08:00
|
|
|
init : () => _dispatch(_trimHash(_hash)),
|
2020-08-12 06:25:36 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set Hash value, generating a new history record.
|
|
|
|
* @param {...string} path Hash value without '#'.
|
2022-03-03 23:28:05 +08:00
|
|
|
* @example hasher.setHash('lorem/ipsum/dolor') -> '#/lorem/ipsum/dolor'
|
2020-08-12 06:25:36 +08:00
|
|
|
*/
|
2022-03-03 23:28:05 +08:00
|
|
|
setHash : path => _setHash(path),
|
2020-08-12 06:25:36 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set Hash value without keeping previous hash on the history record.
|
|
|
|
* @param {...string} path Hash value without '#'.
|
2022-03-03 23:28:05 +08:00
|
|
|
* @example hasher.replaceHash('lorem/ipsum/dolor') -> '#/lorem/ipsum/dolor'
|
2020-08-12 06:25:36 +08:00
|
|
|
*/
|
2022-03-03 23:28:05 +08:00
|
|
|
replaceHash : path => _setHash(path, true)
|
2020-08-12 06:25:36 +08:00
|
|
|
};
|
|
|
|
|
2021-11-01 18:24:11 +08:00
|
|
|
var _hash = _getWindowHash(),
|
|
|
|
_bindings = [];
|
|
|
|
|
2022-03-03 23:28:05 +08:00
|
|
|
addEventListener('hashchange', () => _registerChange(_getWindowHash()));
|
2021-11-01 18:24:11 +08:00
|
|
|
|
2020-08-12 06:25:36 +08:00
|
|
|
global.hasher = hasher;
|
|
|
|
})(this);
|