blockly-samples icon indicating copy to clipboard operation
blockly-samples copied to clipboard

Add localization support for alternate decimal characters

Open Adam-Pasco opened this issue 4 years ago • 4 comments

As far as I can tell, Blockly always expects a floating point number to be represented using a period as the decimal character (e.g., 1.23). While Blockly seems to handle the text for other locales very well (word ordering & direction), it does not seem to handle locales that use the comma as a decimal character (e.g., 1,23).

(Please correct me if I'm mistaken, but I looked at the Localization page and there was no mention of it: https://developers.google.com/blockly/guides/create-custom-blocks/localize-blocks)

I would like support for customizing which decimal character to use, either by (in order of preference):

  1. Some methodology to pass the desired decimal character to the Blockly code
  2. Blockly querying the system's locale settings to determine the appropriate character
  3. A means to allow the user to specify which character to use

Thank you for your consideration.

Adam-Pasco avatar Mar 18 '20 16:03 Adam-Pasco

We will definitely look into this as a feature request. In the meantime, if you need this before we get to it you can look at creating a custom field that extends doClassValidation_. If you have any questions feel free to ask on our forum!

alschmiedt avatar Mar 18 '20 17:03 alschmiedt

I've looked into this a bit before, and it's actually quite a complicated problem to solve smoothly.

Some users want the decimal seperator to match their system/language settings. Others want it to always be a period regardless of their settings. Some people want it to work differently when they're copy-pasting vs when they're typing directly. Etc etc.

For an interesting discussion of this issue I recommend https://github.com/microsoft/calculator/issues/153

BeksOmega avatar Mar 18 '20 18:03 BeksOmega

Thanks for the quick responses. BeksOmega, thanks for the link! That IS an interesting discussion.

Adam-Pasco avatar Mar 18 '20 19:03 Adam-Pasco

This is something we'd support, but is not currently in our planning timeline. This would be arguably be breaking change in behavior so something we'd want to wait on until we were going to do a major release. Therefore instead of changing the default number field, this should be a new field plugin. Anyone who wants this behavior could unregister the default number field and register the plugin one in its place.

Here's an initial plan, which we could certainly discuss further at the time this is picked up.

For output (i.e. the field's text), we can convert the number to a string using toLocaleString and passing in the locale. Currently, we don't store the locale anywhere. Options:

  • We could change the Blockly.setLocale method to store the name of the locale that is passed in, so we can use it later.
    • This only captures language and not country. So, for the locale fr the difference between France and Quebec would not be captured.
    • Also assumes the blockly locales match the standard ones, an assumption that needs validating.
  • We could use navigator.language(s) to get the locale of the browser.
    • May not match the language Blockly is displayed in, which may be confusing.

For input, it's more complicated.

Today's behavior, inside doClassValidation_: commas are assumed to be thousands separators and removed. The string value, after this and other unrelated transformations, is converted to a number using the Number function. Thus, a single period is assumed to be a decimal place, and multiple periods are an error.

Desired behavior: Inspired by the microsoft/calculator discussion above, we'll let people enter commas and periods, regardless of their locale.

  • If both periods and commas appear, we'll assume that the last one in the string is for decimals, and any others are the thousands separators. If you enter two of the character used for decimals, that's a validation error (same as today).
  • If only one type appears, but multiple times, then assume it is a thousands separator and ignore it.
  • Ambiguous case: exactly one separator appears. Options:
    • Just assume it's a decimal because nobody types thousands separators.
    • Check the user's locale and assume they are being using that.
      • but if they are in a locale with commas as the decimal separator, this is confusing to people with experience with text-based programming who are accustomed to using periods anyway. Thus, this does not seem like a good option.
  • Internally, we want to store the value of the block as a number, not a string. So if the decimal character is a comma, we'd first need to strip out any existing periods, and then convert the comma to a period before casting the string to a number.

Additional context from Neil:

  • Blockly has historically ignored this because it is assumed that users are learning to code and will graduate to text-based programming, where they will need to learn to use the period for the decimal. But for other use cases of Blockly like configuration this does not apply.
  • Important to keep in mind that language only does not tell the full story. Quebec uses American-style numbers and dates which are different than in France. But the Blockly language code for both is 'fr'.

maribethb avatar Nov 10 '22 00:11 maribethb