Polish UI and billing flows: route fallback, searchable selectors, light-mode fixes
This commit is contained in:
@@ -279,6 +279,14 @@
|
||||
h2 { font-size: var(--fs-l); font-weight: var(--fw-semibold); line-height: 1.25; }
|
||||
h3 { font-size: var(--fs-m); font-weight: var(--fw-semibold); line-height: 1.3; }
|
||||
html.theme-light .text-white:not(.force-white) { color: var(--app-fg) !important; }
|
||||
html.theme-light button.text-white,
|
||||
html.theme-light a.text-white,
|
||||
html.theme-light [role="button"].text-white,
|
||||
html.theme-light button .text-white,
|
||||
html.theme-light a .text-white,
|
||||
html.theme-light [role="button"] .text-white {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
html.theme-light .text-gray-200 { color: #334155 !important; }
|
||||
html.theme-light .text-gray-300 { color: #475569 !important; }
|
||||
html.theme-light .text-gray-400 { color: var(--muted-text) !important; }
|
||||
@@ -606,67 +614,74 @@
|
||||
</script>
|
||||
<script>
|
||||
(() => {
|
||||
const normalizeCode = (raw) => {
|
||||
const input = String(raw || '').trim().replace('_', '-');
|
||||
if (!input) return null;
|
||||
const parts = input.split('-');
|
||||
if (parts.length === 1) {
|
||||
const code = parts[0].toLowerCase();
|
||||
return /^[a-z]{2,3}$/.test(code) ? code : null;
|
||||
}
|
||||
const base = parts[0].toLowerCase();
|
||||
const region = parts[1].toUpperCase();
|
||||
const code = `${base}-${region}`;
|
||||
return /^[a-z]{2,3}-[A-Z]{2}$/.test(code) ? code : null;
|
||||
const alpha = 'abcdefghijklmnopqrstuvwxyz';
|
||||
const deprecatedAliases = {
|
||||
in: 'id',
|
||||
iw: 'he',
|
||||
ji: 'yi',
|
||||
jw: 'jv',
|
||||
};
|
||||
|
||||
window.dewemojiPopulateLanguageOptions = (target) => {
|
||||
const list = typeof target === 'string' ? document.getElementById(target) : target;
|
||||
if (!list || list.dataset.generated === '1') return;
|
||||
const makeIso6391Codes = () => {
|
||||
const codes = [];
|
||||
for (let i = 0; i < alpha.length; i += 1) {
|
||||
for (let j = 0; j < alpha.length; j += 1) {
|
||||
codes.push(alpha[i] + alpha[j]);
|
||||
}
|
||||
}
|
||||
return codes;
|
||||
};
|
||||
|
||||
const codeToName = new Map();
|
||||
list.querySelectorAll('option[data-code]').forEach((option) => {
|
||||
const code = normalizeCode(option.dataset.code);
|
||||
if (!code) return;
|
||||
const fallbackName = String(option.value || '').replace(/\s+\([^)]+\)\s*$/, '').trim() || code;
|
||||
codeToName.set(code, fallbackName);
|
||||
});
|
||||
const canonicalLanguageCode = (raw) => {
|
||||
const code = String(raw || '').trim().toLowerCase();
|
||||
if (!code) return '';
|
||||
return deprecatedAliases[code] || code;
|
||||
};
|
||||
|
||||
if (!codeToName.has('und')) codeToName.set('und', 'Undetermined');
|
||||
window.dewemojiCanonicalLanguageCode = canonicalLanguageCode;
|
||||
|
||||
if (typeof Intl !== 'undefined' && typeof Intl.supportedValuesOf === 'function') {
|
||||
const display = typeof Intl.DisplayNames === 'function'
|
||||
? new Intl.DisplayNames(['en'], { type: 'language' })
|
||||
: null;
|
||||
window.dewemojiPopulateLanguageSelect = (target) => {
|
||||
const select = typeof target === 'string' ? document.getElementById(target) : target;
|
||||
if (!(select instanceof HTMLSelectElement) || select.dataset.generated === '1') return;
|
||||
|
||||
Intl.supportedValuesOf('language').forEach((rawCode) => {
|
||||
const code = normalizeCode(rawCode);
|
||||
if (!code) return;
|
||||
const name = display?.of(code) || display?.of(code.split('-')[0]) || code;
|
||||
codeToName.set(code, name);
|
||||
const existing = Array.from(select.options).map((opt) => ({
|
||||
code: canonicalLanguageCode(opt.value),
|
||||
label: (opt.textContent || '').trim(),
|
||||
})).filter((row) => row.code !== '');
|
||||
|
||||
const byCode = new Map(existing.map((row) => [row.code.toLowerCase(), row]));
|
||||
|
||||
if (typeof Intl !== 'undefined' && typeof Intl.DisplayNames === 'function') {
|
||||
const dn = new Intl.DisplayNames(['en'], { type: 'language' });
|
||||
makeIso6391Codes().forEach((code) => {
|
||||
const name = dn.of(code);
|
||||
if (!name) return;
|
||||
// Unknown/unsupported codes are echoed back by many engines.
|
||||
if (name.toLowerCase() === code) return;
|
||||
const canonical = canonicalLanguageCode(code);
|
||||
if (!canonical) return;
|
||||
byCode.set(canonical, { code: canonical, label: `${name} (${canonical})` });
|
||||
});
|
||||
}
|
||||
|
||||
const entries = Array.from(codeToName.entries()).sort((a, b) => {
|
||||
if (a[0] === 'und') return -1;
|
||||
if (b[0] === 'und') return 1;
|
||||
return a[1].localeCompare(b[1]);
|
||||
const rows = Array.from(byCode.values()).sort((a, b) => {
|
||||
if (a.code === 'und') return -1;
|
||||
if (b.code === 'und') return 1;
|
||||
return a.label.localeCompare(b.label);
|
||||
});
|
||||
|
||||
list.innerHTML = '';
|
||||
entries.forEach(([code, name]) => {
|
||||
const previous = (select.value || '').trim().toLowerCase();
|
||||
select.innerHTML = '';
|
||||
rows.forEach((row) => {
|
||||
const option = document.createElement('option');
|
||||
option.value = `${name} (${code})`;
|
||||
option.dataset.code = code;
|
||||
list.appendChild(option);
|
||||
option.value = row.code;
|
||||
option.textContent = row.label;
|
||||
select.appendChild(option);
|
||||
});
|
||||
|
||||
list.dataset.generated = '1';
|
||||
select.value = previous || select.value;
|
||||
select.dataset.generated = '1';
|
||||
};
|
||||
|
||||
document.querySelectorAll('datalist[data-language-options="1"]').forEach((list) => {
|
||||
window.dewemojiPopulateLanguageOptions(list);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
@stack('scripts')
|
||||
|
||||
Reference in New Issue
Block a user