From d14fd0f70ed984c4c97e07215e5c9bdc344de4f1 Mon Sep 17 00:00:00 2001 From: Robert Lord Date: Sat, 20 Jun 2015 01:49:25 -0400 Subject: [PATCH] Update language tabs to not disturb existing query strings, fixes #57 --- source/javascripts/app/_lang.js | 88 +++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/source/javascripts/app/_lang.js b/source/javascripts/app/_lang.js index c3b48ed..79d3903 100644 --- a/source/javascripts/app/_lang.js +++ b/source/javascripts/app/_lang.js @@ -40,6 +40,83 @@ under the License. } } + // parseURL and stringifyURL are from https://github.com/sindresorhus/query-string + // MIT licensed + // https://github.com/sindresorhus/query-string/blob/7bee64c16f2da1a326579e96977b9227bf6da9e6/license + function parseURL(str) { + if (typeof str !== 'string') { + return {}; + } + + str = str.trim().replace(/^(\?|#|&)/, ''); + + if (!str) { + return {}; + } + + return str.split('&').reduce(function (ret, param) { + var parts = param.replace(/\+/g, ' ').split('='); + var key = parts[0]; + var val = parts[1]; + + key = decodeURIComponent(key); + // missing `=` should be `null`: + // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters + val = val === undefined ? null : decodeURIComponent(val); + + if (!ret.hasOwnProperty(key)) { + ret[key] = val; + } else if (Array.isArray(ret[key])) { + ret[key].push(val); + } else { + ret[key] = [ret[key], val]; + } + + return ret; + }, {}); + }; + + function stringifyURL(obj) { + return obj ? Object.keys(obj).sort().map(function (key) { + var val = obj[key]; + + if (Array.isArray(val)) { + return val.sort().map(function (val2) { + return encodeURIComponent(key) + '=' + encodeURIComponent(val2); + }).join('&'); + } + + return encodeURIComponent(key) + '=' + encodeURIComponent(val); + }).join('&') : ''; + }; + + // gets the language set in the query string + function getLanguageFromQueryString() { + if (location.search.length >= 1) { + var language = parseURL(location.search).language + if (language) { + return language; + } else if (jQuery.inArray(location.search.substr(1), languages) != -1) { + return location.search.substr(1); + } + } + + return false; + } + + // returns a new query string with the new language in it + function generateNewQueryString(language) { + if (location.search.length >= 1) { + var url = parseURL(location.search); + if (url.language) { + url.language = language; + return stringifyURL(url); + } else { + return language + } + } + } + // if a button is clicked, add the state to the history function pushURL(language) { if (!history) { return; } @@ -47,7 +124,7 @@ under the License. if (hash) { hash = hash.replace(/^#+/, ''); } - history.pushState({}, '', '?' + language + '#' + hash); + history.pushState({}, '', '?' + generateNewQueryString(language) + '#' + hash); // save language as next default localStorage.setItem("language", language); @@ -58,11 +135,12 @@ under the License. languages = l; - if ((location.search.substr(1) !== "") && (jQuery.inArray(location.search.substr(1), languages)) != -1) { + var presetLanguage = getLanguageFromQueryString(); + if (presetLanguage) { // the language is in the URL, so use that language! - activateLanguage(location.search.substr(1)); + activateLanguage(presetLanguage); - localStorage.setItem("language", location.search.substr(1)); + localStorage.setItem("language", presetLanguage); } else if ((defaultLanguage !== null) && (jQuery.inArray(defaultLanguage, languages) != -1)) { // the language was the last selected one saved in localstorage, so use that language! activateLanguage(defaultLanguage); @@ -81,7 +159,7 @@ under the License. return false; }); window.onpopstate = function() { - activateLanguage(window.location.search.substr(1)); + activateLanguage(getLanguageFromQueryString()); }; }); })(window);