Skip to content

Commit 4c3fcef

Browse files
authored
Merge pull request #5411 from kh-ub-ayb/selected-language
Added visual highlight for selected language in dropdown
2 parents a2a1924 + ae01b21 commit 4c3fcef

File tree

3 files changed

+106
-4
lines changed

3 files changed

+106
-4
lines changed

css/themes.css

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
.dark #confirmation-message {
144144
color: #e2e2e2;
145145
}
146+
146147
body {
147148
--border: #cccccc;
148149
--bg: #ffffff;
@@ -159,4 +160,16 @@ body.dark {
159160
--accent: #3fe0d1;
160161
}
161162

162-
/* Your Custom Theme can go here if you don't want to modify the existing dark mode */
163+
/* Your Custom Theme can go here if you don't want to modify the existing dark mode */
164+
165+
/* Selected language highlight in language dropdown */
166+
#languagedropdown li a.selected-language {
167+
background-color: rgba(33, 150, 243, 0.15);
168+
border-left: 3px solid #2196F3;
169+
font-weight: 600;
170+
}
171+
172+
.dark #languagedropdown li a.selected-language {
173+
background-color: rgba(33, 150, 243, 0.25);
174+
border-left: 3px solid #64B5F6;
175+
}

js/__tests__/toolbar.test.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -886,8 +886,25 @@ describe("Toolbar Class", () => {
886886

887887
test("renderLanguageSelectIcon sets onclick and updates language selection", () => {
888888
const languageSelectIcon = { onclick: null };
889-
const languageBox = { setAttribute: jest.fn() };
890-
global.docById.mockReturnValue(languageSelectIcon);
889+
const languageBox = { enUS_onclick: jest.fn() };
890+
891+
// Mock elements for all language IDs with classList
892+
const mockLangElement = {
893+
onclick: null,
894+
classList: {
895+
add: jest.fn(),
896+
remove: jest.fn()
897+
}
898+
};
899+
900+
global.docById.mockImplementation(id => {
901+
if (id === "languageSelectIcon") return languageSelectIcon;
902+
// Return mock element with classList for any language ID
903+
return mockLangElement;
904+
});
905+
906+
global.localStorage.languagePreference = "enUS";
907+
891908
toolbar.renderLanguageSelectIcon(languageBox);
892909
expect(languageSelectIcon.onclick).toBeInstanceOf(Function);
893910
languageSelectIcon.onclick();

js/toolbar.js

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1178,9 +1178,81 @@ class Toolbar {
11781178
"ur"
11791179
];
11801180

1181+
/**
1182+
* Updates the selected-language class to highlight the currently selected language.
1183+
* @param {string} selectedLang - The language code to highlight.
1184+
*/
1185+
const updateSelectedLanguageHighlight = selectedLang => {
1186+
// Remove existing selection from all language items
1187+
languages.forEach(lang => {
1188+
const langElem = docById(lang);
1189+
if (langElem) {
1190+
langElem.classList.remove("selected-language");
1191+
}
1192+
});
1193+
1194+
// Handle special cases for language preference storage values and browser language codes
1195+
let langToHighlight = selectedLang;
1196+
1197+
// Map browser language codes to dropdown IDs
1198+
const browserLangMap = {
1199+
"en-US": "enUS",
1200+
"en-GB": "enUK",
1201+
"en-UK": "enUK",
1202+
"zh-CN": "zhCN",
1203+
"zh": "zhCN"
1204+
};
1205+
1206+
// Check if it's a browser language code that needs mapping
1207+
if (selectedLang && browserLangMap[selectedLang]) {
1208+
langToHighlight = browserLangMap[selectedLang];
1209+
}
1210+
1211+
// Handle Japanese variants (ja-kanji, ja-kana stored vs ja/kana displayed)
1212+
if (selectedLang && selectedLang.startsWith("ja")) {
1213+
if (selectedLang === "ja-kana" || localStorage.kanaPreference === "kana") {
1214+
langToHighlight = "kana";
1215+
} else {
1216+
langToHighlight = "ja";
1217+
}
1218+
}
1219+
1220+
// Handle zh_CN to zhCN mapping (stored preference format)
1221+
if (selectedLang === "zh_CN") {
1222+
langToHighlight = "zhCN";
1223+
}
1224+
1225+
// Fallback: if language starts with "en" but not mapped, default to enUS
1226+
if (
1227+
selectedLang &&
1228+
selectedLang.startsWith("en") &&
1229+
!languages.includes(langToHighlight)
1230+
) {
1231+
langToHighlight = "enUS";
1232+
}
1233+
1234+
const selectedElem = docById(langToHighlight);
1235+
if (selectedElem) {
1236+
selectedElem.classList.add("selected-language");
1237+
}
1238+
};
1239+
11811240
languageSelectIcon.onclick = () => {
1241+
// Get current language preference
1242+
const currentLang = localStorage.languagePreference || navigator.language;
1243+
1244+
// Highlight the currently selected language
1245+
updateSelectedLanguageHighlight(currentLang);
1246+
1247+
// Set up click handlers for each language
11821248
languages.forEach(lang => {
1183-
docById(lang).onclick = () => languageBox[`${lang}_onclick`](this.activity);
1249+
docById(lang).onclick = () => {
1250+
// Update highlight to newly selected language
1251+
updateSelectedLanguageHighlight(lang);
1252+
1253+
// Call the original language change handler
1254+
languageBox[`${lang}_onclick`](this.activity);
1255+
};
11841256
});
11851257
};
11861258
}

0 commit comments

Comments
 (0)