Skip to content

Update the negotiation and Locale logic to match latest algo#335

Merged
zbraniecki merged 2 commits into
projectfluent:masterfrom
zbraniecki:zh-hk
Feb 7, 2019
Merged

Update the negotiation and Locale logic to match latest algo#335
zbraniecki merged 2 commits into
projectfluent:masterfrom
zbraniecki:zh-hk

Conversation

@zbraniecki

Copy link
Copy Markdown
Collaborator

This patch brings the JS implementation very close to the C++ and Rust implementations.

@zbraniecki zbraniecki requested a review from stasm February 6, 2019 14:38
@zbraniecki

Copy link
Copy Markdown
Collaborator Author

it removes the * as an option for language tag, because we really never need it. Instead it uses ranges on match method which is what we do in C++ and Rust.

@zbraniecki

Copy link
Copy Markdown
Collaborator Author

Fixes #334

Comment thread fluent-langneg/src/locale.js Outdated
const language = result[1] || undefined;
const script = result[2] || undefined;
const region = result[3] || undefined;
const variant = result[4] || undefined;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be written more succinctly as: let [, language, script, region, variant] = result.

Comment thread fluent-langneg/src/locale.js Outdated
this.language = language.toLowerCase();
}
if (script) {
this.script = script[0].toUpperCase() + script.substr(1);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use slice or substring, as substr is considered a legacy function.

Comment thread fluent-langneg/src/subtags.js Outdated
"ta": "ta-taml-in",
"uk": "uk-cyrl-ua",
"zh": "zh-hans-cn",
"zh-hant": "zh-Hant-TW",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please be consistent with letter case, or comment on the reason why it needs to be inconsistent if that's the case.

Comment thread fluent-langneg/src/matches.js Outdated

const availLocales =
new Set(availableLocales.map(locale => new Locale(locale, true)));
const availLocales = new Map();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's take the opportunity to fix the cryptic naming here. availableLocales vs availLocales hides the difference between the two. I suggest availableLanguageTags and availableLanguagesByTag, respectively.

Comment thread fluent-langneg/src/matches.js Outdated
break;
}
}
for (const key of availLocales.keys()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename key to tag? (Here and elsewhere.)

this[part].toLowerCase() === locale[part].toLowerCase());
return ((thisRange && this[part] === undefined) ||
(otherRange && locale[part] === undefined) ||
this[part] === locale[part]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understanding this method is important for understanding the whole algorithm and I'm not fond of adding two boolean arguments to it. It's hard to follow what they mean when the method is called. In fact, I think I largely preferred the old code which used an explicit * to represent ranges.

A few suggestions on how to improve this code. I'm not saying all of them need to be applied at the same time, but I'd like to see this method improved somehow.

  • Remove the thisRange param as it is always true across all callsites, or start using it for exact matching.
  • Use an options dictionary: locale.matches(other, {thisRange: true, otherRange: true}).
  • Separate this code into multiple methods: exactMatches, matchesThisRange, matchesRanges.
  • Add a flag to Locale called undefinedAsRange and a method called toRange() which returns a new Locale instance based on the one the method was called on. match would inspect the value of the flag for both this and other and act accordingly.

Now, I understand that this code is based on the existing C++/Rust code. With that in mind, I think this can be moved to a follow-up. Please file it if you agree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants