var hashchange = (function () { var exports = {}; var expected_hash; var changing_hash = false; // Some browsers zealously URI-decode the contents of // window.location.hash. So we hide our URI-encoding // by replacing % with . (like MediaWiki). exports.encodeHashComponent = function (str) { return encodeURIComponent(str) .replace(/\./g, '%2E') .replace(/%/g, '.'); }; function decodeHashComponent(str) { return decodeURIComponent(str.replace(/\./g, '%')); } function set_hash(hash) { var location = window.location; if (history.pushState) { if (hash === '' || hash.charAt(0) !== '#') { hash = '#' + hash; } // IE returns pathname as undefined and missing the leading / var pathname = location.pathname; if (pathname === undefined) { pathname = '/'; } else if (pathname === '' || pathname.charAt(0) !== '/') { pathname = '/' + pathname; } // Build a full URL to not have same origin problems var url = location.protocol + '//' + location.host + pathname + hash; history.pushState(null, null, url); } else { location.hash = hash; } } exports.changehash = function (newhash) { if (changing_hash) { return; } $(document).trigger($.Event('hashchange.zulip')); set_hash(newhash); favicon.reset(); }; // Encodes an operator list into the // corresponding hash: the # component // of the narrow URL exports.operators_to_hash = function (operators) { var hash = '#'; if (operators !== undefined) { hash = '#narrow'; _.each(operators, function (elem) { // Support legacy tuples. var operator = elem.operator; var operand = elem.operand; var sign = elem.negated ? '-' : ''; hash += '/' + sign + hashchange.encodeHashComponent(operator) + '/' + hashchange.encodeHashComponent(operand); }); } return hash; }; exports.save_narrow = function (operators) { if (changing_hash) { return; } var new_hash = exports.operators_to_hash(operators); exports.changehash(new_hash); }; function parse_narrow(hash) { var i, operators = []; for (i=1; i