2012-12-07 20:52:39 +01:00
|
|
|
var hashchange = (function () {
|
|
|
|
|
|
|
|
var exports = {};
|
|
|
|
|
2013-04-09 19:17:42 +02:00
|
|
|
var expected_hash;
|
2013-04-03 20:44:26 +02:00
|
|
|
var changing_hash = false;
|
2012-12-07 20:52:39 +01:00
|
|
|
|
2013-03-20 00:22:51 +01:00
|
|
|
// Some browsers zealously URI-decode the contents of
|
|
|
|
// window.location.hash. So we hide our URI-encoding
|
|
|
|
// by replacing % with . (like MediaWiki).
|
|
|
|
|
2013-07-05 17:43:56 +02:00
|
|
|
exports.encodeHashComponent = function (str) {
|
2013-03-20 00:22:51 +01:00
|
|
|
return encodeURIComponent(str)
|
|
|
|
.replace(/\./g, '%2E')
|
|
|
|
.replace(/%/g, '.');
|
2013-05-02 16:45:38 +02:00
|
|
|
};
|
2013-03-20 00:22:51 +01:00
|
|
|
|
|
|
|
function decodeHashComponent(str) {
|
|
|
|
return decodeURIComponent(str.replace(/\./g, '%'));
|
|
|
|
}
|
|
|
|
|
2012-12-07 20:52:39 +01:00
|
|
|
exports.changehash = function (newhash) {
|
2013-04-03 20:44:26 +02:00
|
|
|
if (changing_hash) {
|
|
|
|
return;
|
|
|
|
}
|
2013-07-25 22:48:55 +02:00
|
|
|
$(document).trigger($.Event('hashchange.zulip'));
|
2012-12-07 20:52:39 +01:00
|
|
|
expected_hash = newhash;
|
2013-01-11 16:57:17 +01:00
|
|
|
// Some browsers reset scrollTop when changing the hash to "",
|
2012-12-19 21:19:29 +01:00
|
|
|
// so we save and restore it.
|
|
|
|
// http://stackoverflow.com/questions/4715073/window-location-hash-prevent-scrolling-to-the-top
|
2013-02-15 22:41:36 +01:00
|
|
|
var scrolltop = viewport.scrollTop();
|
2012-12-07 20:52:39 +01:00
|
|
|
window.location.hash = newhash;
|
2012-12-19 21:19:29 +01:00
|
|
|
util.reset_favicon();
|
2013-02-15 22:41:36 +01:00
|
|
|
if (newhash === "" || newhash === "#") {
|
2012-12-19 21:19:29 +01:00
|
|
|
viewport.scrollTop(scrolltop);
|
|
|
|
}
|
2012-12-07 20:52:39 +01:00
|
|
|
};
|
|
|
|
|
2013-05-09 21:12:53 +02:00
|
|
|
// 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 (idx, elem) {
|
|
|
|
hash += '/' + hashchange.encodeHashComponent(elem[0])
|
|
|
|
+ '/' + hashchange.encodeHashComponent(elem[1]);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return hash;
|
|
|
|
};
|
|
|
|
|
2012-12-12 19:00:50 +01:00
|
|
|
exports.save_narrow = function (operators) {
|
2013-04-03 20:44:26 +02:00
|
|
|
if (changing_hash) {
|
|
|
|
return;
|
|
|
|
}
|
2013-05-09 21:12:53 +02:00
|
|
|
var new_hash = exports.operators_to_hash(operators);
|
|
|
|
exports.changehash(new_hash);
|
2012-12-12 19:00:50 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
function parse_narrow(hash) {
|
|
|
|
var i, operators = [];
|
|
|
|
for (i=1; i<hash.length; i+=2) {
|
|
|
|
// We don't construct URLs with an odd number of components,
|
|
|
|
// but the user might write one.
|
2013-05-02 17:38:29 +02:00
|
|
|
try {
|
|
|
|
var operator = decodeHashComponent(hash[i]);
|
|
|
|
var operand = decodeHashComponent(hash[i+1] || '');
|
|
|
|
operators.push([operator, operand]);
|
|
|
|
} catch (err) {
|
|
|
|
return undefined;
|
|
|
|
}
|
2012-12-12 19:00:50 +01:00
|
|
|
}
|
2013-05-02 17:38:29 +02:00
|
|
|
return operators;
|
|
|
|
}
|
|
|
|
|
|
|
|
function activate_home_tab() {
|
|
|
|
ui.change_tab_to("#home");
|
|
|
|
narrow.deactivate();
|
|
|
|
ui.update_floating_recipient_bar();
|
2012-12-12 19:00:50 +01:00
|
|
|
}
|
|
|
|
|
2012-12-21 01:04:27 +01:00
|
|
|
// Returns true if this function performed a narrow
|
2013-04-03 20:44:26 +02:00
|
|
|
function do_hashchange() {
|
2012-12-07 20:52:39 +01:00
|
|
|
// If window.location.hash changed because our app explicitly
|
|
|
|
// changed it, then we don't need to do anything.
|
|
|
|
// (This function only neds to jump into action if it changed
|
|
|
|
// because e.g. the back button was pressed by the user)
|
2013-04-09 19:17:42 +02:00
|
|
|
//
|
|
|
|
// The second case is for handling the fact that some browsers
|
|
|
|
// automatically convert '#' to '' when you change the hash to '#'.
|
|
|
|
if (window.location.hash === expected_hash ||
|
|
|
|
(expected_hash !== undefined &&
|
|
|
|
window.location.hash.replace(/^#/, '') === '' &&
|
|
|
|
expected_hash.replace(/^#/, '') === '')) {
|
2012-12-21 01:04:27 +01:00
|
|
|
return false;
|
2012-12-07 20:52:39 +01:00
|
|
|
}
|
|
|
|
|
2013-07-25 22:48:55 +02:00
|
|
|
$(document).trigger($.Event('hashchange.zulip'));
|
2013-04-23 21:59:49 +02:00
|
|
|
|
2013-03-20 00:22:51 +01:00
|
|
|
// NB: In Firefox, window.location.hash is URI-decoded.
|
|
|
|
// Even if the URL bar says #%41%42%43%44, the value here will
|
|
|
|
// be #ABCD.
|
2012-12-07 20:52:39 +01:00
|
|
|
var hash = window.location.hash.split("/");
|
2012-12-19 21:19:29 +01:00
|
|
|
switch (hash[0]) {
|
|
|
|
case "#narrow":
|
|
|
|
ui.change_tab_to("#home");
|
2013-05-02 17:38:29 +02:00
|
|
|
var operators = parse_narrow(hash);
|
|
|
|
if (operators === undefined) {
|
|
|
|
// If the narrow URL didn't parse, clear
|
|
|
|
// window.location.hash and send them to the home tab
|
|
|
|
window.location.hash = '';
|
|
|
|
activate_home_tab();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
narrow.activate(operators, {
|
|
|
|
select_first_unread: true,
|
2013-05-21 19:34:15 +02:00
|
|
|
change_hash: false, // already set
|
|
|
|
trigger: 'hash change'
|
2013-05-02 17:38:29 +02:00
|
|
|
});
|
2012-12-19 21:19:29 +01:00
|
|
|
ui.update_floating_recipient_bar();
|
2012-12-21 01:04:27 +01:00
|
|
|
return true;
|
2012-12-19 21:19:29 +01:00
|
|
|
case "":
|
|
|
|
case "#":
|
2013-05-02 17:38:29 +02:00
|
|
|
activate_home_tab();
|
2012-12-19 21:19:29 +01:00
|
|
|
break;
|
|
|
|
case "#subscriptions":
|
|
|
|
ui.change_tab_to("#subscriptions");
|
|
|
|
break;
|
|
|
|
case "#settings":
|
|
|
|
ui.change_tab_to("#settings");
|
|
|
|
break;
|
2012-12-07 20:52:39 +01:00
|
|
|
}
|
2012-12-21 01:04:27 +01:00
|
|
|
return false;
|
2012-12-07 20:52:39 +01:00
|
|
|
}
|
|
|
|
|
2013-04-03 20:44:26 +02:00
|
|
|
function hashchanged() {
|
|
|
|
changing_hash = true;
|
|
|
|
var ret = do_hashchange();
|
|
|
|
changing_hash = false;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-12-07 20:52:39 +01:00
|
|
|
exports.initialize = function () {
|
2013-04-03 18:55:28 +02:00
|
|
|
// jQuery doesn't have a hashchange event, so we manually wrap
|
|
|
|
// our event handler
|
|
|
|
window.onhashchange = blueslip.wrap_function(hashchanged);
|
2013-04-10 17:55:02 +02:00
|
|
|
hashchanged();
|
2012-12-07 20:52:39 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
return exports;
|
|
|
|
|
|
|
|
}());
|