You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
2.6 KiB
111 lines
2.6 KiB
'use strict'; |
|
|
|
var LocationActions = require('../actions/LocationActions'); |
|
var History = require('../History'); |
|
|
|
var _listeners = []; |
|
var _isListening = false; |
|
var _actionType; |
|
|
|
function notifyChange(type) { |
|
if (type === LocationActions.PUSH) History.length += 1; |
|
|
|
var change = { |
|
path: HashLocation.getCurrentPath(), |
|
type: type |
|
}; |
|
|
|
_listeners.forEach(function (listener) { |
|
listener.call(HashLocation, change); |
|
}); |
|
} |
|
|
|
function ensureSlash() { |
|
var path = HashLocation.getCurrentPath(); |
|
|
|
if (path.charAt(0) === '/') { |
|
return true; |
|
}HashLocation.replace('/' + path); |
|
|
|
return false; |
|
} |
|
|
|
function onHashChange() { |
|
if (ensureSlash()) { |
|
// If we don't have an _actionType then all we know is the hash |
|
// changed. It was probably caused by the user clicking the Back |
|
// button, but may have also been the Forward button or manual |
|
// manipulation. So just guess 'pop'. |
|
var curActionType = _actionType; |
|
_actionType = null; |
|
notifyChange(curActionType || LocationActions.POP); |
|
} |
|
} |
|
|
|
/** |
|
* A Location that uses `window.location.hash`. |
|
*/ |
|
var HashLocation = { |
|
|
|
addChangeListener: function addChangeListener(listener) { |
|
_listeners.push(listener); |
|
|
|
// Do this BEFORE listening for hashchange. |
|
ensureSlash(); |
|
|
|
if (!_isListening) { |
|
if (window.addEventListener) { |
|
window.addEventListener('hashchange', onHashChange, false); |
|
} else { |
|
window.attachEvent('onhashchange', onHashChange); |
|
} |
|
|
|
_isListening = true; |
|
} |
|
}, |
|
|
|
removeChangeListener: function removeChangeListener(listener) { |
|
_listeners = _listeners.filter(function (l) { |
|
return l !== listener; |
|
}); |
|
|
|
if (_listeners.length === 0) { |
|
if (window.removeEventListener) { |
|
window.removeEventListener('hashchange', onHashChange, false); |
|
} else { |
|
window.removeEvent('onhashchange', onHashChange); |
|
} |
|
|
|
_isListening = false; |
|
} |
|
}, |
|
|
|
push: function push(path) { |
|
_actionType = LocationActions.PUSH; |
|
window.location.hash = path; |
|
}, |
|
|
|
replace: function replace(path) { |
|
_actionType = LocationActions.REPLACE; |
|
window.location.replace(window.location.pathname + window.location.search + '#' + path); |
|
}, |
|
|
|
pop: function pop() { |
|
_actionType = LocationActions.POP; |
|
History.back(); |
|
}, |
|
|
|
getCurrentPath: function getCurrentPath() { |
|
return decodeURI( |
|
// We can't use window.location.hash here because it's not |
|
// consistent across browsers - Firefox will pre-decode it! |
|
window.location.href.split('#')[1] || ''); |
|
}, |
|
|
|
toString: function toString() { |
|
return '<HashLocation>'; |
|
} |
|
|
|
}; |
|
|
|
module.exports = HashLocation; |