From 1b74005ee9747f167d22ff0888c24b6383e173ba Mon Sep 17 00:00:00 2001 From: Adriano Raiano Date: Wed, 23 Mar 2022 17:42:53 +0100 Subject: [PATCH] fix querystring lookup if happening after # (fragment) --- CHANGELOG.md | 4 ++++ i18nextBrowserLanguageDetector.js | 8 +++++++- i18nextBrowserLanguageDetector.min.js | 2 +- src/browserLookups/querystring.js | 8 ++++++-- test/languageDetector.test.js | 14 ++++++++++++++ 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b22372a..172d19d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +### 6.1.4 + +- fix querystring lookup if happening after # [256](https://github.com/i18next/i18next-browser-languageDetector/issues/256) + ### 6.1.3 - export DecetorOptions and CustomDetector types diff --git a/i18nextBrowserLanguageDetector.js b/i18nextBrowserLanguageDetector.js index 5569c4e..cfef641 100644 --- a/i18nextBrowserLanguageDetector.js +++ b/i18nextBrowserLanguageDetector.js @@ -173,7 +173,13 @@ var found; if (typeof window !== 'undefined') { - var query = window.location.search.substring(1); + var search = window.location.search; + + if (!window.location.search && window.location.hash && window.location.hash.indexOf('?') > -1) { + search = window.location.hash.substring(window.location.hash.indexOf('?')); + } + + var query = search.substring(1); var params = query.split('&'); for (var i = 0; i < params.length; i++) { diff --git a/i18nextBrowserLanguageDetector.min.js b/i18nextBrowserLanguageDetector.min.js index 263fdd4..7b96d81 100644 --- a/i18nextBrowserLanguageDetector.min.js +++ b/i18nextBrowserLanguageDetector.min.js @@ -1 +1 @@ -!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self).i18nextBrowserLanguageDetector=o()}(this,(function(){"use strict";function e(e,o){if(!(e instanceof o))throw new TypeError("Cannot call a class as a function")}function o(e,o){for(var t=0;t0){var a=n.maxAge-0;if(isNaN(a))throw new Error("maxAge should be a Number");i+="; Max-Age="+Math.floor(a)}if(n.domain){if(!r.test(n.domain))throw new TypeError("option domain is invalid");i+="; Domain="+n.domain}if(n.path){if(!r.test(n.path))throw new TypeError("option path is invalid");i+="; Path="+n.path}if(n.expires){if("function"!=typeof n.expires.toUTCString)throw new TypeError("option expires is invalid");i+="; Expires="+n.expires.toUTCString()}if(n.httpOnly&&(i+="; HttpOnly"),n.secure&&(i+="; Secure"),n.sameSite)switch("string"==typeof n.sameSite?n.sameSite.toLowerCase():n.sameSite){case!0:i+="; SameSite=Strict";break;case"lax":i+="; SameSite=Lax";break;case"strict":i+="; SameSite=Strict";break;case"none":i+="; SameSite=None";break;default:throw new TypeError("option sameSite is invalid")}return i},u=function(e,o,t,n){var i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{path:"/",sameSite:"strict"};t&&(i.expires=new Date,i.expires.setTime(i.expires.getTime()+60*t*1e3)),n&&(i.domain=n),document.cookie=s(e,encodeURIComponent(o),i)},l=function(e){for(var o=e+"=",t=document.cookie.split(";"),n=0;n0)t[n].substring(0,i)===e.lookupQuerystring&&(o=t[n].substring(i+1))}return o}},d=null,f=function(){if(null!==d)return d;try{d="undefined"!==window&&null!==window.localStorage;var e="i18next.translate.boo";window.localStorage.setItem(e,"foo"),window.localStorage.removeItem(e)}catch(e){d=!1}return d},g={name:"localStorage",lookup:function(e){var o;if(e.lookupLocalStorage&&f()){var t=window.localStorage.getItem(e.lookupLocalStorage);t&&(o=t)}return o},cacheUserLanguage:function(e,o){o.lookupLocalStorage&&f()&&window.localStorage.setItem(o.lookupLocalStorage,e)}},h=null,m=function(){if(null!==h)return h;try{h="undefined"!==window&&null!==window.sessionStorage;var e="i18next.translate.boo";window.sessionStorage.setItem(e,"foo"),window.sessionStorage.removeItem(e)}catch(e){h=!1}return h},v={name:"sessionStorage",lookup:function(e){var o;if(e.lookupSessionStorage&&m()){var t=window.sessionStorage.getItem(e.lookupSessionStorage);t&&(o=t)}return o},cacheUserLanguage:function(e,o){o.lookupSessionStorage&&m()&&window.sessionStorage.setItem(o.lookupSessionStorage,e)}},k={name:"navigator",lookup:function(e){var o=[];if("undefined"!=typeof navigator){if(navigator.languages)for(var t=0;t0?o:void 0}},w={name:"htmlTag",lookup:function(e){var o,t=e.htmlTag||("undefined"!=typeof document?document.documentElement:null);return t&&"function"==typeof t.getAttribute&&(o=t.getAttribute("lang")),o}},S={name:"path",lookup:function(e){var o;if("undefined"!=typeof window){var t=window.location.pathname.match(/\/([a-zA-Z-]*)/g);if(t instanceof Array)if("number"==typeof e.lookupFromPathIndex){if("string"!=typeof t[e.lookupFromPathIndex])return;o=t[e.lookupFromPathIndex].replace("/","")}else o=t[0].replace("/","")}return o}},y={name:"subdomain",lookup:function(e){var o;if("undefined"!=typeof window){var t=window.location.href.match(/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/gi);t instanceof Array&&(o="number"==typeof e.lookupFromSubdomainIndex?t[e.lookupFromSubdomainIndex].replace("http://","").replace("https://","").replace(".",""):t[0].replace("http://","").replace("https://","").replace(".",""))}return o}};var x=function(){function t(o){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e(this,t),this.type="languageDetector",this.detectors={},this.init(o,n)}var n,i,r;return n=t,i=[{key:"init",value:function(e){var o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.services=e,this.options=a(o,this.options||{},{order:["querystring","cookie","localStorage","sessionStorage","navigator","htmlTag"],lookupQuerystring:"lng",lookupCookie:"i18next",lookupLocalStorage:"i18nextLng",lookupSessionStorage:"i18nextLng",caches:["localStorage"],excludeCacheFor:["cimode"]}),this.options.lookupFromUrlIndex&&(this.options.lookupFromPathIndex=this.options.lookupFromUrlIndex),this.i18nOptions=t,this.addDetector(c),this.addDetector(p),this.addDetector(g),this.addDetector(v),this.addDetector(k),this.addDetector(w),this.addDetector(S),this.addDetector(y)}},{key:"addDetector",value:function(e){this.detectors[e.name]=e}},{key:"detect",value:function(e){var o=this;e||(e=this.options.order);var t=[];return e.forEach((function(e){if(o.detectors[e]){var n=o.detectors[e].lookup(o.options);n&&"string"==typeof n&&(n=[n]),n&&(t=t.concat(n))}})),this.services.languageUtils.getBestMatchFromCodes?t:t.length>0?t[0]:null}},{key:"cacheUserLanguage",value:function(e,o){var t=this;o||(o=this.options.caches),o&&(this.options.excludeCacheFor&&this.options.excludeCacheFor.indexOf(e)>-1||o.forEach((function(o){t.detectors[o]&&t.detectors[o].cacheUserLanguage(e,t.options)})))}}],i&&o(n.prototype,i),r&&o(n,r),Object.defineProperty(n,"prototype",{writable:!1}),t}();return x.type="languageDetector",x})); +!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self).i18nextBrowserLanguageDetector=o()}(this,(function(){"use strict";function e(e,o){if(!(e instanceof o))throw new TypeError("Cannot call a class as a function")}function o(e,o){for(var t=0;t0){var a=n.maxAge-0;if(isNaN(a))throw new Error("maxAge should be a Number");i+="; Max-Age="+Math.floor(a)}if(n.domain){if(!r.test(n.domain))throw new TypeError("option domain is invalid");i+="; Domain="+n.domain}if(n.path){if(!r.test(n.path))throw new TypeError("option path is invalid");i+="; Path="+n.path}if(n.expires){if("function"!=typeof n.expires.toUTCString)throw new TypeError("option expires is invalid");i+="; Expires="+n.expires.toUTCString()}if(n.httpOnly&&(i+="; HttpOnly"),n.secure&&(i+="; Secure"),n.sameSite)switch("string"==typeof n.sameSite?n.sameSite.toLowerCase():n.sameSite){case!0:i+="; SameSite=Strict";break;case"lax":i+="; SameSite=Lax";break;case"strict":i+="; SameSite=Strict";break;case"none":i+="; SameSite=None";break;default:throw new TypeError("option sameSite is invalid")}return i},u=function(e,o,t,n){var i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{path:"/",sameSite:"strict"};t&&(i.expires=new Date,i.expires.setTime(i.expires.getTime()+60*t*1e3)),n&&(i.domain=n),document.cookie=s(e,encodeURIComponent(o),i)},l=function(e){for(var o=e+"=",t=document.cookie.split(";"),n=0;n-1&&(t=window.location.hash.substring(window.location.hash.indexOf("?")));for(var n=t.substring(1).split("&"),i=0;i0)n[i].substring(0,a)===e.lookupQuerystring&&(o=n[i].substring(a+1))}}return o}},p=null,f=function(){if(null!==p)return p;try{p="undefined"!==window&&null!==window.localStorage;var e="i18next.translate.boo";window.localStorage.setItem(e,"foo"),window.localStorage.removeItem(e)}catch(e){p=!1}return p},g={name:"localStorage",lookup:function(e){var o;if(e.lookupLocalStorage&&f()){var t=window.localStorage.getItem(e.lookupLocalStorage);t&&(o=t)}return o},cacheUserLanguage:function(e,o){o.lookupLocalStorage&&f()&&window.localStorage.setItem(o.lookupLocalStorage,e)}},h=null,m=function(){if(null!==h)return h;try{h="undefined"!==window&&null!==window.sessionStorage;var e="i18next.translate.boo";window.sessionStorage.setItem(e,"foo"),window.sessionStorage.removeItem(e)}catch(e){h=!1}return h},v={name:"sessionStorage",lookup:function(e){var o;if(e.lookupSessionStorage&&m()){var t=window.sessionStorage.getItem(e.lookupSessionStorage);t&&(o=t)}return o},cacheUserLanguage:function(e,o){o.lookupSessionStorage&&m()&&window.sessionStorage.setItem(o.lookupSessionStorage,e)}},w={name:"navigator",lookup:function(e){var o=[];if("undefined"!=typeof navigator){if(navigator.languages)for(var t=0;t0?o:void 0}},k={name:"htmlTag",lookup:function(e){var o,t=e.htmlTag||("undefined"!=typeof document?document.documentElement:null);return t&&"function"==typeof t.getAttribute&&(o=t.getAttribute("lang")),o}},S={name:"path",lookup:function(e){var o;if("undefined"!=typeof window){var t=window.location.pathname.match(/\/([a-zA-Z-]*)/g);if(t instanceof Array)if("number"==typeof e.lookupFromPathIndex){if("string"!=typeof t[e.lookupFromPathIndex])return;o=t[e.lookupFromPathIndex].replace("/","")}else o=t[0].replace("/","")}return o}},y={name:"subdomain",lookup:function(e){var o;if("undefined"!=typeof window){var t=window.location.href.match(/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/gi);t instanceof Array&&(o="number"==typeof e.lookupFromSubdomainIndex?t[e.lookupFromSubdomainIndex].replace("http://","").replace("https://","").replace(".",""):t[0].replace("http://","").replace("https://","").replace(".",""))}return o}};var x=function(){function t(o){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e(this,t),this.type="languageDetector",this.detectors={},this.init(o,n)}var n,i,r;return n=t,i=[{key:"init",value:function(e){var o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.services=e,this.options=a(o,this.options||{},{order:["querystring","cookie","localStorage","sessionStorage","navigator","htmlTag"],lookupQuerystring:"lng",lookupCookie:"i18next",lookupLocalStorage:"i18nextLng",lookupSessionStorage:"i18nextLng",caches:["localStorage"],excludeCacheFor:["cimode"]}),this.options.lookupFromUrlIndex&&(this.options.lookupFromPathIndex=this.options.lookupFromUrlIndex),this.i18nOptions=t,this.addDetector(c),this.addDetector(d),this.addDetector(g),this.addDetector(v),this.addDetector(w),this.addDetector(k),this.addDetector(S),this.addDetector(y)}},{key:"addDetector",value:function(e){this.detectors[e.name]=e}},{key:"detect",value:function(e){var o=this;e||(e=this.options.order);var t=[];return e.forEach((function(e){if(o.detectors[e]){var n=o.detectors[e].lookup(o.options);n&&"string"==typeof n&&(n=[n]),n&&(t=t.concat(n))}})),this.services.languageUtils.getBestMatchFromCodes?t:t.length>0?t[0]:null}},{key:"cacheUserLanguage",value:function(e,o){var t=this;o||(o=this.options.caches),o&&(this.options.excludeCacheFor&&this.options.excludeCacheFor.indexOf(e)>-1||o.forEach((function(o){t.detectors[o]&&t.detectors[o].cacheUserLanguage(e,t.options)})))}}],i&&o(n.prototype,i),r&&o(n,r),Object.defineProperty(n,"prototype",{writable:!1}),t}();return x.type="languageDetector",x})); diff --git a/src/browserLookups/querystring.js b/src/browserLookups/querystring.js index 7482fea..05f2924 100644 --- a/src/browserLookups/querystring.js +++ b/src/browserLookups/querystring.js @@ -5,8 +5,12 @@ export default { let found; if (typeof window !== 'undefined') { - let query = window.location.search.substring(1); - let params = query.split('&'); + let search = window.location.search; + if (!window.location.search && window.location.hash && window.location.hash.indexOf('?') > -1) { + search = window.location.hash.substring(window.location.hash.indexOf('?')) + } + const query = search.substring(1); + const params = query.split('&'); for (let i=0; i 0) { diff --git a/test/languageDetector.test.js b/test/languageDetector.test.js index 6e74597..c545bac 100644 --- a/test/languageDetector.test.js +++ b/test/languageDetector.test.js @@ -52,4 +52,18 @@ describe('language detector', () => { expect(lng).to.contain('de') }) }) + + describe('querystring (fragment)', () => { + it('detect', () => { + global.window = { + location: { + pathname: '/fr/some/route', + hash: '#/something?lng=de', + search: '' + } + } + const lng = ld.detect() + expect(lng).to.contain('de') + }) + }) })