Skip to content

Commit c5b371f

Browse files
authored
Fix getSystemEnvironment crash on web when a locale region is undefined (#5447)
Handle a case when Int.Locale('...') is created without a region - then use an empty string for region. Fixes https://youtrack.jetbrains.com/issue/CMP-6930 ## Testing - Added a test - This should be tested by QA ## Release Notes ### Fixes - Resources - Fix a crash when calling `getString` and the Locale has no region specified
1 parent 238a4f6 commit c5b371f

File tree

3 files changed

+62
-4
lines changed

3 files changed

+62
-4
lines changed

components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.js.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import kotlinx.browser.window
55
private external class Intl {
66
class Locale(locale: String) {
77
val language: String
8-
val region: String
8+
9+
// Intl.Locale.region can be undefined.
10+
// For example, new Int.Locale('en') instead of new Int.Locale('en-NL').
11+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/region
12+
val region: String?
913
}
1014
}
1115

@@ -16,7 +20,7 @@ internal actual fun getSystemEnvironment(): ResourceEnvironment {
1620
val dpi: Int = (window.devicePixelRatio * 96).toInt()
1721
return ResourceEnvironment(
1822
language = LanguageQualifier(locale.language),
19-
region = RegionQualifier(locale.region),
23+
region = RegionQualifier(locale.region ?: ""),
2024
theme = ThemeQualifier.selectByValue(isDarkTheme),
2125
density = DensityQualifier.selectByValue(dpi)
2226
)

components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.wasmJs.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import kotlinx.browser.window
55
private external class Intl {
66
class Locale(locale: String) {
77
val language: String
8-
val region: String
8+
9+
// Intl.Locale.region can be undefined.
10+
// For example, new Int.Locale('en') instead of new Int.Locale('en-NL').
11+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/region
12+
val region: String?
913
}
1014
}
1115

@@ -16,7 +20,7 @@ internal actual fun getSystemEnvironment(): ResourceEnvironment {
1620
val dpi: Int = (window.devicePixelRatio * 96).toInt()
1721
return ResourceEnvironment(
1822
language = LanguageQualifier(locale.language),
19-
region = RegionQualifier(locale.region),
23+
region = RegionQualifier(locale.region ?: ""),
2024
theme = ThemeQualifier.selectByValue(isDarkTheme),
2125
density = DensityQualifier.selectByValue(dpi)
2226
)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package org.jetbrains.compose.resources
2+
3+
import kotlinx.browser.window
4+
import kotlin.test.Test
5+
import kotlin.test.assertEquals
6+
7+
class ResourceEnvironmentTest {
8+
9+
// covers https://youtrack.jetbrains.com/issue/CMP-6930 (also see the comments)
10+
@Test
11+
fun usingLocaleWithoutRegion() {
12+
val originalLanguage = window.navigator.language
13+
configureLanguage("en")
14+
15+
try {
16+
val env = getSystemEnvironment()
17+
assertEquals("", env.region.region)
18+
assertEquals("en", env.language.language)
19+
} finally {
20+
configureLanguage(originalLanguage)
21+
}
22+
}
23+
24+
@Test
25+
fun usingLocaleWithRegion() {
26+
val originalLanguage = window.navigator.language
27+
configureLanguage("en-NL")
28+
29+
try {
30+
val env = getSystemEnvironment()
31+
assertEquals("NL", env.region.region)
32+
assertEquals("en", env.language.language)
33+
} finally {
34+
configureLanguage(originalLanguage)
35+
}
36+
37+
}
38+
}
39+
40+
//language=js
41+
private fun configureLanguage(language: String) {
42+
js("""
43+
Object.defineProperty(window.navigator, 'language', {
44+
get: function () {
45+
return language;
46+
},
47+
configurable: true
48+
});
49+
""")
50+
}

0 commit comments

Comments
 (0)