Skip to content

Commit 0a7da06

Browse files
committed
Fix template-require-lang-attribute: validate every BCP47 subtag
Port only validated parts[0] against a small set; upstream validates every hyphen-separated subtag (region/script). Add the missing country-codes table and traverse all subtags. lang="en-XX" is now correctly flagged.
1 parent 56f913d commit 0a7da06

3 files changed

Lines changed: 675 additions & 3 deletions

File tree

lib/rules/template-require-lang-attribute.js

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
// Common valid BCP 47 language tags (not exhaustive, but covers the most common)
1+
const COUNTRY_CODES = require('../utils/country-codes');
2+
3+
// Common valid BCP 47 primary language subtags (not exhaustive, but covers the most common).
4+
// Used as a fast-path check for the primary subtag; full validation of every
5+
// hyphen-separated subtag is performed against COUNTRY_CODES (mirroring
6+
// ember-template-lint's upstream behavior).
27
const COMMON_LANG_CODES = new Set([
38
'aa',
49
'ab',
@@ -193,9 +198,30 @@ function isValidLangTag(value) {
193198
if (!value || !value.trim()) {
194199
return false;
195200
}
196-
const parts = value.trim().toLowerCase().split('-');
201+
const normalized = value.trim().toLowerCase();
202+
const parts = normalized.split('-');
203+
204+
// Primary subtag must be a known language code. Keep the original
205+
// COMMON_LANG_CODES fast-path so bare tags like "zh" remain valid even
206+
// when they are not present in the full country-codes table.
207+
if (!COMMON_LANG_CODES.has(parts[0])) {
208+
// Fallback: the whole value may be a registered grandfathered/irregular
209+
// tag (e.g. "zh-hant", "sgn-gb").
210+
return COUNTRY_CODES.includes(normalized);
211+
}
212+
213+
// Validate every remaining hyphen-separated subtag (region / script /
214+
// variant) against the full country-codes table, mirroring upstream
215+
// ember-template-lint. A whole-string match against COUNTRY_CODES is
216+
// also accepted to cover multi-part registered tags.
217+
if (parts.length === 1) {
218+
return true;
219+
}
197220

198-
return COMMON_LANG_CODES.has(parts[0]);
221+
return (
222+
parts.slice(1).every((p) => COUNTRY_CODES.includes(p)) ||
223+
COUNTRY_CODES.includes(normalized)
224+
);
199225
}
200226

201227
function parseConfig(config) {

0 commit comments

Comments
 (0)