'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 ''; } }; module.exports = HashLocation;