diff --git a/CHANGELOG.md b/CHANGELOG.md index 8971f05..1ff7c55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +### 8.0.2 + +- fix for when passed services are null, should address [296](https://github.com/i18next/i18next-browser-languageDetector/issues/296) + ### 8.0.1 - some environments, throws when accessing document.cookie diff --git a/i18nextBrowserLanguageDetector.js b/i18nextBrowserLanguageDetector.js index 539a490..572151e 100644 --- a/i18nextBrowserLanguageDetector.js +++ b/i18nextBrowserLanguageDetector.js @@ -306,6 +306,7 @@ } }; + // some environments, throws when accessing document.cookie let canCookies = false; try { // eslint-disable-next-line no-unused-expressions @@ -375,7 +376,7 @@ } }); detected = detected.map(d => this.options.convertDetectedLanguage(d)); - if (this.services.languageUtils.getBestMatchFromCodes) return detected; // new i18next v19.5.0 + if (this.services && this.services.languageUtils && this.services.languageUtils.getBestMatchFromCodes) return detected; // new i18next v19.5.0 return detected.length > 0 ? detected[0] : null; // a little backward compatibility } cacheUserLanguage(lng) { diff --git a/i18nextBrowserLanguageDetector.min.js b/i18nextBrowserLanguageDetector.min.js index 97272fb..7e2b58f 100644 --- a/i18nextBrowserLanguageDetector.min.js +++ b/i18nextBrowserLanguageDetector.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).i18nextBrowserLanguageDetector=t()}(this,(function(){"use strict";const{slice:e,forEach:t}=[];const o=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/,n={create(e,t,n,i){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{path:"/",sameSite:"strict"};n&&(r.expires=new Date,r.expires.setTime(r.expires.getTime()+60*n*1e3)),i&&(r.domain=i),document.cookie=function(e,t){const n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{path:"/"};let i=`${e}=${encodeURIComponent(t)}`;if(n.maxAge>0){const e=n.maxAge-0;if(Number.isNaN(e))throw new Error("maxAge should be a Number");i+=`; Max-Age=${Math.floor(e)}`}if(n.domain){if(!o.test(n.domain))throw new TypeError("option domain is invalid");i+=`; Domain=${n.domain}`}if(n.path){if(!o.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}(e,encodeURIComponent(t),r)},read(e){const t=`${e}=`,o=document.cookie.split(";");for(let e=0;e-1&&(e=window.location.hash.substring(window.location.hash.indexOf("?")));const n=e.substring(1).split("&");for(let e=0;e0){n[e].substring(0,i)===o&&(t=n[e].substring(i+1))}}}return t}};let a=null;const s=()=>{if(null!==a)return a;try{a="undefined"!==window&&null!==window.localStorage;const e="i18next.translate.boo";window.localStorage.setItem(e,"foo"),window.localStorage.removeItem(e)}catch(e){a=!1}return a};var l={name:"localStorage",lookup(e){let{lookupLocalStorage:t}=e;if(t&&s())return window.localStorage.getItem(t)||void 0},cacheUserLanguage(e,t){let{lookupLocalStorage:o}=t;o&&s()&&window.localStorage.setItem(o,e)}};let c=null;const u=()=>{if(null!==c)return c;try{c="undefined"!==window&&null!==window.sessionStorage;const e="i18next.translate.boo";window.sessionStorage.setItem(e,"foo"),window.sessionStorage.removeItem(e)}catch(e){c=!1}return c};var d={name:"sessionStorage",lookup(e){let{lookupSessionStorage:t}=e;if(t&&u())return window.sessionStorage.getItem(t)||void 0},cacheUserLanguage(e,t){let{lookupSessionStorage:o}=t;o&&u()&&window.sessionStorage.setItem(o,e)}},g={name:"navigator",lookup(e){const t=[];if("undefined"!=typeof navigator){const{languages:e,userLanguage:o,language:n}=navigator;if(e)for(let o=0;o0?t:void 0}},h={name:"htmlTag",lookup(e){let t,{htmlTag:o}=e;const n=o||("undefined"!=typeof document?document.documentElement:null);return n&&"function"==typeof n.getAttribute&&(t=n.getAttribute("lang")),t}},p={name:"path",lookup(e){let{lookupFromPathIndex:t}=e;if("undefined"==typeof window)return;const o=window.location.pathname.match(/\/([a-zA-Z-]*)/g);if(!Array.isArray(o))return;const n="number"==typeof t?t:0;return o[n]?.replace("/","")}},f={name:"subdomain",lookup(e){let{lookupFromSubdomainIndex:t}=e;const o="number"==typeof t?t+1:1,n="undefined"!=typeof window&&window.location?.hostname?.match(/^(\w{2,5})\.(([a-z0-9-]{1,63}\.[a-z]{2,6})|localhost)/i);if(n)return n[o]}};let m=!1;try{document.cookie,m=!0}catch(e){}const w=["querystring","cookie","localStorage","sessionStorage","navigator","htmlTag"];m||w.splice(1,1);class S{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.type="languageDetector",this.detectors={},this.init(e,t)}init(){let o=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{languageUtils:{}},n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.services=o,this.options=function(o){return t.call(e.call(arguments,1),(e=>{if(e)for(const t in e)void 0===o[t]&&(o[t]=e[t])})),o}(n,this.options||{},{order:w,lookupQuerystring:"lng",lookupCookie:"i18next",lookupLocalStorage:"i18nextLng",lookupSessionStorage:"i18nextLng",caches:["localStorage"],excludeCacheFor:["cimode"],convertDetectedLanguage:e=>e}),"string"==typeof this.options.convertDetectedLanguage&&this.options.convertDetectedLanguage.indexOf("15897")>-1&&(this.options.convertDetectedLanguage=e=>e.replace("-","_")),this.options.lookupFromUrlIndex&&(this.options.lookupFromPathIndex=this.options.lookupFromUrlIndex),this.i18nOptions=a,this.addDetector(i),this.addDetector(r),this.addDetector(l),this.addDetector(d),this.addDetector(g),this.addDetector(h),this.addDetector(p),this.addDetector(f)}addDetector(e){return this.detectors[e.name]=e,this}detect(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.options.order,t=[];return e.forEach((e=>{if(this.detectors[e]){let o=this.detectors[e].lookup(this.options);o&&"string"==typeof o&&(o=[o]),o&&(t=t.concat(o))}})),t=t.map((e=>this.options.convertDetectedLanguage(e))),this.services.languageUtils.getBestMatchFromCodes?t:t.length>0?t[0]:null}cacheUserLanguage(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.options.caches;t&&(this.options.excludeCacheFor&&this.options.excludeCacheFor.indexOf(e)>-1||t.forEach((t=>{this.detectors[t]&&this.detectors[t].cacheUserLanguage(e,this.options)})))}}return S.type="languageDetector",S})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).i18nextBrowserLanguageDetector=t()}(this,(function(){"use strict";const{slice:e,forEach:t}=[];const o=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/,n={create(e,t,n,i){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{path:"/",sameSite:"strict"};n&&(r.expires=new Date,r.expires.setTime(r.expires.getTime()+60*n*1e3)),i&&(r.domain=i),document.cookie=function(e,t){const n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{path:"/"};let i=`${e}=${encodeURIComponent(t)}`;if(n.maxAge>0){const e=n.maxAge-0;if(Number.isNaN(e))throw new Error("maxAge should be a Number");i+=`; Max-Age=${Math.floor(e)}`}if(n.domain){if(!o.test(n.domain))throw new TypeError("option domain is invalid");i+=`; Domain=${n.domain}`}if(n.path){if(!o.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}(e,encodeURIComponent(t),r)},read(e){const t=`${e}=`,o=document.cookie.split(";");for(let e=0;e-1&&(e=window.location.hash.substring(window.location.hash.indexOf("?")));const n=e.substring(1).split("&");for(let e=0;e0){n[e].substring(0,i)===o&&(t=n[e].substring(i+1))}}}return t}};let a=null;const s=()=>{if(null!==a)return a;try{a="undefined"!==window&&null!==window.localStorage;const e="i18next.translate.boo";window.localStorage.setItem(e,"foo"),window.localStorage.removeItem(e)}catch(e){a=!1}return a};var l={name:"localStorage",lookup(e){let{lookupLocalStorage:t}=e;if(t&&s())return window.localStorage.getItem(t)||void 0},cacheUserLanguage(e,t){let{lookupLocalStorage:o}=t;o&&s()&&window.localStorage.setItem(o,e)}};let c=null;const u=()=>{if(null!==c)return c;try{c="undefined"!==window&&null!==window.sessionStorage;const e="i18next.translate.boo";window.sessionStorage.setItem(e,"foo"),window.sessionStorage.removeItem(e)}catch(e){c=!1}return c};var d={name:"sessionStorage",lookup(e){let{lookupSessionStorage:t}=e;if(t&&u())return window.sessionStorage.getItem(t)||void 0},cacheUserLanguage(e,t){let{lookupSessionStorage:o}=t;o&&u()&&window.sessionStorage.setItem(o,e)}},g={name:"navigator",lookup(e){const t=[];if("undefined"!=typeof navigator){const{languages:e,userLanguage:o,language:n}=navigator;if(e)for(let o=0;o0?t:void 0}},h={name:"htmlTag",lookup(e){let t,{htmlTag:o}=e;const n=o||("undefined"!=typeof document?document.documentElement:null);return n&&"function"==typeof n.getAttribute&&(t=n.getAttribute("lang")),t}},p={name:"path",lookup(e){let{lookupFromPathIndex:t}=e;if("undefined"==typeof window)return;const o=window.location.pathname.match(/\/([a-zA-Z-]*)/g);if(!Array.isArray(o))return;const n="number"==typeof t?t:0;return o[n]?.replace("/","")}},f={name:"subdomain",lookup(e){let{lookupFromSubdomainIndex:t}=e;const o="number"==typeof t?t+1:1,n="undefined"!=typeof window&&window.location?.hostname?.match(/^(\w{2,5})\.(([a-z0-9-]{1,63}\.[a-z]{2,6})|localhost)/i);if(n)return n[o]}};let m=!1;try{document.cookie,m=!0}catch(e){}const w=["querystring","cookie","localStorage","sessionStorage","navigator","htmlTag"];m||w.splice(1,1);class S{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.type="languageDetector",this.detectors={},this.init(e,t)}init(){let o=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{languageUtils:{}},n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.services=o,this.options=function(o){return t.call(e.call(arguments,1),(e=>{if(e)for(const t in e)void 0===o[t]&&(o[t]=e[t])})),o}(n,this.options||{},{order:w,lookupQuerystring:"lng",lookupCookie:"i18next",lookupLocalStorage:"i18nextLng",lookupSessionStorage:"i18nextLng",caches:["localStorage"],excludeCacheFor:["cimode"],convertDetectedLanguage:e=>e}),"string"==typeof this.options.convertDetectedLanguage&&this.options.convertDetectedLanguage.indexOf("15897")>-1&&(this.options.convertDetectedLanguage=e=>e.replace("-","_")),this.options.lookupFromUrlIndex&&(this.options.lookupFromPathIndex=this.options.lookupFromUrlIndex),this.i18nOptions=a,this.addDetector(i),this.addDetector(r),this.addDetector(l),this.addDetector(d),this.addDetector(g),this.addDetector(h),this.addDetector(p),this.addDetector(f)}addDetector(e){return this.detectors[e.name]=e,this}detect(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.options.order,t=[];return e.forEach((e=>{if(this.detectors[e]){let o=this.detectors[e].lookup(this.options);o&&"string"==typeof o&&(o=[o]),o&&(t=t.concat(o))}})),t=t.map((e=>this.options.convertDetectedLanguage(e))),this.services&&this.services.languageUtils&&this.services.languageUtils.getBestMatchFromCodes?t:t.length>0?t[0]:null}cacheUserLanguage(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.options.caches;t&&(this.options.excludeCacheFor&&this.options.excludeCacheFor.indexOf(e)>-1||t.forEach((t=>{this.detectors[t]&&this.detectors[t].cacheUserLanguage(e,this.options)})))}}return S.type="languageDetector",S})); diff --git a/src/index.js b/src/index.js index 8cebf9e..a3401f8 100644 --- a/src/index.js +++ b/src/index.js @@ -81,7 +81,7 @@ class Browser { detected = detected.map((d) => this.options.convertDetectedLanguage(d)); - if (this.services.languageUtils.getBestMatchFromCodes) return detected; // new i18next v19.5.0 + if (this.services && this.services.languageUtils && this.services.languageUtils.getBestMatchFromCodes) return detected; // new i18next v19.5.0 return detected.length > 0 ? detected[0] : null; // a little backward compatibility }