Skip to content

Commit

Permalink
CLDR-17080 Regional Variants menu follow-up (#3372)
Browse files Browse the repository at this point in the history
-Set SIDEWAYS_DEBUG to false

-Remove the 2-second delay if (and only if) the user has just chosen from the menu

-Shorten excessively long functions by moving nested functions to top level and making more subroutines

-Refactor for clarity

-Comments
  • Loading branch information
btangmu authored Nov 7, 2023
1 parent dc6b3fe commit f502341
Show file tree
Hide file tree
Showing 2 changed files with 170 additions and 132 deletions.
283 changes: 161 additions & 122 deletions tools/cldr-apps/js/src/esm/cldrSideways.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,48 @@ import * as cldrLoad from "./cldrLoad.mjs";
import * as cldrStatus from "./cldrStatus.mjs";
import * as cldrSurvey from "./cldrSurvey.mjs";

const SIDEWAYS_DEBUG = true;
const SIDEWAYS_DEBUG = false;

const escape = "\u00A0\u00A0\u00A0"; // non-breaking spaces
const unequalSign = "\u2260\u00A0"; // U+2260 = "≠"
const NON_BREAKING_SPACES = "\u00A0\u00A0\u00A0"; // non-breaking spaces
const UNEQUALS_SIGN = "\u2260\u00A0"; // U+2260 = "≠"

/**
* Array storing all only-1 sublocales
*/
const oneLocales = [];

/**
* Timeout for showing sideways view
* Ordinarily, wait a couple seconds before fetching the data for the menu.
* One reason for this delay is that the Info Panel is often shown for a given
* row only briefly before the user moves on to the next row, and there's a
* performance penalty if the data is fetched unnecessarily. At the end of the
* delay, if the current row has changed, the fetch will be cancelled.
* However, when the user chooses a related locale from the menu, there
* should be no delay.
*/
let sidewaysShowTimeout = -1;
const USUAL_DELAY_MILLISECONDS = 2000;
const ZERO_DELAY_MILLISECONDS = 0;

let fetchDelayMilliseconds = USUAL_DELAY_MILLISECONDS;

/**
* Timeout ID for fetching and showing the menu
*/
let sidewaysShowTimeoutId = -1;

const sidewaysCache = new cldrCache.LRU();

let locmap = null;

let curLocale = null;

function loadMenu(regionalVariantsWrapper, xpstrid) {
const curLocale = cldrStatus.getCurrentLocale();
if (!locmap) {
locmap = cldrLoad.getTheLocaleMap();
}
curLocale = cldrStatus.getCurrentLocale();
if (!curLocale || oneLocales[curLocale] || !xpstrid) {
regionalVariantsWrapper.setData(null);
regionalVariantsWrapper.setData(null, null);
if (SIDEWAYS_DEBUG) {
console.log("cldrSideways.loadMenu, nothing to display");
}
Expand All @@ -40,24 +61,19 @@ function loadMenu(regionalVariantsWrapper, xpstrid) {
if (SIDEWAYS_DEBUG) {
console.log("cldrSideways.loadMenu, using cached data");
}
regionalVariantsWrapper.setData(cachedData);
regionalVariantsWrapper.setData(curLocale, cachedData);
} else {
if (SIDEWAYS_DEBUG) {
console.log("cldrSideways.loadMenu, fetching new data");
}
fetchAndLoadMenu(regionalVariantsWrapper, curLocale, xpstrid, cacheKey);
fetchAndLoadMenu(regionalVariantsWrapper, xpstrid, cacheKey);
}
}

function fetchAndLoadMenu(
regionalVariantsWrapper,
curLocale,
xpstrid,
cacheKey
) {
function fetchAndLoadMenu(regionalVariantsWrapper, xpstrid, cacheKey) {
clearMyTimeout();
regionalVariantsWrapper.setLoading();
sidewaysShowTimeout = window.setTimeout(function () {
sidewaysShowTimeoutId = window.setTimeout(function () {
clearMyTimeout();
if (
curLocale !== cldrStatus.getCurrentLocale() ||
Expand All @@ -77,14 +93,15 @@ function fetchAndLoadMenu(
setMenuFromData(regionalVariantsWrapper, json, cacheKey);
}
);
}, 2000); // wait 2 seconds before loading this.
}, fetchDelayMilliseconds);
fetchDelayMilliseconds = USUAL_DELAY_MILLISECONDS;
}

function clearMyTimeout() {
if (sidewaysShowTimeout != -1) {
if (sidewaysShowTimeoutId != -1) {
// https://www.w3schools.com/jsref/met_win_clearinterval.asp
window.clearInterval(sidewaysShowTimeout);
sidewaysShowTimeout = -1;
window.clearInterval(sidewaysShowTimeoutId);
sidewaysShowTimeoutId = -1;
}
}

Expand Down Expand Up @@ -121,115 +138,131 @@ function setMenuFromData(regionalVariantsWrapper, json, cacheKey) {
}
// if there is 1 sublocale (+ 1 default), show nothing
if (Object.keys(relatedLocales).length <= 2) {
oneLocales[cldrStatus.getCurrentLocale()] = true;
regionalVariantsWrapper.setData(null);
oneLocales[curLocale] = true;
regionalVariantsWrapper.setData(null, null);
} else {
if (!json.others) {
regionalVariantsWrapper.setData(null);
regionalVariantsWrapper.setData(null, null);
} else {
const topLocale = json.topLocale;
const locmap = cldrLoad.getTheLocaleMap();
const curLocaleName = locmap.getRegionAndOrVariantName(topLocale);
let readLocale = null;

// merge the read-only sublocale to base locale
var mergeReadBase = function mergeReadBase(list) {
let baseValue = null;
// find the base locale, remove it and store its value
for (let l = 0; l < list.length; l++) {
const loc = list[l][0];
if (loc === topLocale) {
baseValue = list[l][1];
list.splice(l, 1);
break;
}
}

// replace the default locale(read-only) with base locale, store its name for label
for (let l = 0; l < list.length; l++) {
const loc = list[l][0];
const bund = locmap.getLocaleInfo(loc);
if (bund && bund.readonly) {
readLocale = locmap.getRegionAndOrVariantName(loc);
list[l][0] = topLocale;
list[l][1] = baseValue;
break;
}
}
};

// compare all sublocale values
function appendLocaleList(list, curValue) {
popupSelect.label = "Regional Variants for " + curLocaleName;

for (let l = 0; l < list.length; l++) {
const loc = list[l][0];
const title = list[l][1];
const item = { value: loc };
let str = locmap.getRegionAndOrVariantName(loc);
if (loc === topLocale) {
str += " (= " + readLocale + ")";
}

if (loc === cldrStatus.getCurrentLocale()) {
str = escape + str;
item.disabled = true;
} else if (title != curValue) {
str = unequalSign + str;
item.disabled = false;
} else {
str = escape + str;
item.disabled = false;
}
item.str = str;
popupSelect.items.push(item);
}
}
setMenuFromNontrivialData(regionalVariantsWrapper, json, cacheKey);
}
}
}

const dataList = [];
const popupSelect = {};
popupSelect.items = [];
for (let s in json.others) {
for (let t in json.others[s]) {
dataList.push([json.others[s][t], s]);
}
}
function setMenuFromNontrivialData(regionalVariantsWrapper, json, cacheKey) {
const dataList = initializeDataList(json.others);
const curValue = getCurrentValue(dataList);

/*
* Set curValue = the value for cldrStatus.getCurrentLocale()
*/
let curValue = null;
for (let l = 0; l < dataList.length; l++) {
const loc = dataList[l][0];
if (loc === cldrStatus.getCurrentLocale()) {
curValue = dataList[l][1];
break;
}
}
/*
* Force the use of unequalSign in the regional comparison pop-up for locales in
* json.novalue, by assigning a value that's different from curValue.
*/
if (json.novalue) {
const differentValue = curValue === "A" ? "B" : "A"; // anything different from curValue
for (let s in json.novalue) {
dataList.push([json.novalue[s], differentValue]);
}
}
mergeReadBase(dataList);
/*
* Force the use of unequalSign in the regional comparison pop-up for locales in
* json.novalue, by assigning a value that's different from curValue.
*/
if (json.novalue) {
const differentValue = curValue === "A" ? "B" : "A"; // anything different from curValue
for (let s in json.novalue) {
dataList.push([json.novalue[s], differentValue]);
}
}
const readLocale = mergeReadBase(dataList, json.topLocale);

// then sort by sublocale name
const sortedDataList = dataList.sort(function (a, b) {
return (
locmap.getRegionAndOrVariantName(a[0]) >
locmap.getRegionAndOrVariantName(b[0])
);
});
appendLocaleList(sortedDataList, curValue);
sidewaysCache.set(cacheKey, popupSelect);
regionalVariantsWrapper.setData(popupSelect);
// then sort by sublocale name
const sortedDataList = dataList.sort(function (a, b) {
return (
locmap.getRegionAndOrVariantName(a[0]) >
locmap.getRegionAndOrVariantName(b[0])
);
});
const popupSelect = appendLocaleList(
sortedDataList,
curValue,
json.topLocale,
readLocale
);
sidewaysCache.set(cacheKey, popupSelect);
regionalVariantsWrapper.setData(curLocale, popupSelect);
}

function initializeDataList(others) {
const dataList = [];
for (let s in others) {
for (let t in others[s]) {
dataList.push([others[s][t], s]);
}
}
return dataList;
}

/**
* Get the value for the current locale
*/
function getCurrentValue(dataList) {
for (let l = 0; l < dataList.length; l++) {
const loc = dataList[l][0];
if (loc === curLocale) {
return dataList[l][1];
}
}
return null;
}

// merge the read-only sublocale to base locale
function mergeReadBase(list, topLocale) {
let readLocale = null;
let baseValue = null;
// find the base locale, remove it and store its value
for (let l = 0; l < list.length; l++) {
const loc = list[l][0];
if (loc === topLocale) {
baseValue = list[l][1];
list.splice(l, 1);
break;
}
}

// replace the default locale(read-only) with base locale, store its name for label
for (let l = 0; l < list.length; l++) {
const loc = list[l][0];
const bund = locmap.getLocaleInfo(loc);
if (bund && bund.readonly) {
readLocale = locmap.getRegionAndOrVariantName(loc);
list[l][0] = topLocale;
list[l][1] = baseValue;
break;
}
}
return readLocale;
}

function appendLocaleList(list, curValue, topLocale, readLocale) {
const popupSelect = {
items: [],
label:
"Regional Variants for " + locmap.getRegionAndOrVariantName(topLocale),
};
// compare all sublocale values
for (let l = 0; l < list.length; l++) {
const loc = list[l][0];
const title = list[l][1];
const item = { value: loc };
let str = locmap.getRegionAndOrVariantName(loc);
if (loc === topLocale) {
str += " (= " + readLocale + ")";
}

if (loc === curLocale) {
str = NON_BREAKING_SPACES + str;
item.disabled = true;
} else if (title != curValue) {
str = UNEQUALS_SIGN + str;
item.disabled = false;
} else {
str = NON_BREAKING_SPACES + str;
item.disabled = false;
}
item.str = str;
popupSelect.items.push(item);
}
return popupSelect;
}

function makeCacheKey(curLocale, xpstrid) {
Expand All @@ -240,4 +273,10 @@ function clearCache() {
sidewaysCache.clear();
}

export { clearCache, loadMenu };
function goToLocale(localeId) {
cldrStatus.setCurrentLocale(localeId);
cldrLoad.reloadV();
fetchDelayMilliseconds = ZERO_DELAY_MILLISECONDS;
}

export { clearCache, goToLocale, loadMenu };
Loading

0 comments on commit f502341

Please sign in to comment.