blob: f8f04ea07f73788a12275347a037d7b914d636de [file] [log] [blame]
<!DOCTYPE html>
<script src="../../../resources/js-test.js"></script>
<script>
if (window.internals)
internals.settings.setLangAttributeAwareFormControlUIEnabled(true);
else
debug('Require testRunner.');
</script>
<input id="input-ar" lang="ar-eg" type="number">
<input id="input-fr" lang="fr-fr" type="number">
<input id="input-en" lang="en-us" type="number">
<script>
function displayValueForKeyInput(inputElement, keyInputs, optionalOldString, expectedValue) {
inputElement.value = '';
inputElement.focus();
if (optionalOldString) {
let caretPosition = optionalOldString.indexOf('|');
if (caretPosition < 0)
caretPosition = optionalOldString.length;
else
optionalOldString = optionalOldString.replace("|", "");
document.execCommand('InsertText', false, optionalOldString);
// Check that the value is what we expect
inputElement.select();
shouldBeEqualToString("window.getSelection().toString()", optionalOldString);
// Update selection
internals.setSelectionRangeForNumberType(inputElement, caretPosition, caretPosition);
}
document.execCommand('InsertText', false, keyInputs);
inputElement.select();
// Check expected value
if (expectedValue === undefined)
shouldBeUndefined(inputElement.value);
else
shouldBeEqualToNumber(inputElement.value, expectedValue);
return window.getSelection().toString();
}
// Get language formats
var langs = ["ar-eg", "fr-fr", "en-us"];
var langSpecs = {};
var numberCharMapByLang = {};
// Check local formatting options
for (var lang of langs)
{
var formatted = Number(123456.7).toLocaleString(lang);
var oneFormatted = Number(1).toLocaleString(lang);
var negativeFormatted = Number(-1).toLocaleString(lang);
var oneIndex = negativeFormatted.indexOf(oneFormatted);
var negativePrefix = "";
if (oneIndex > 0)
negativePrefix = negativeFormatted.substr(0, oneIndex);
var negativeSuffix = "";
if (negativeSuffix === oneFormatted)
negativeSuffix = negativeFormatted.substr(oneIndex + 1);
var specs = {
"usesCommas": /123,456/.test(formatted),
"usesArabicDecimalSeparator": formatted.indexOf("\u066b") !== -1,
"latinDigits": formatted.indexOf("1") !== -1,
"negativePrefix": negativePrefix,
"negativePrefixLength": negativePrefix.length,
"negativeSuffix": negativeSuffix,
"negativeSuffixLength": negativeSuffix.length,
"usesE": /[eE]/.test(Number(1e2).toLocaleString(lang, {"notation": "scientific"}))
};
specs.usesSingleCharFiltering = (specs.negativePrefixLength == 1 && specs.negativeSuffixLength == 0);
langSpecs[lang] = specs;
// Get replacement digits
numberCharMapByLang[lang] = {};
var formattedDigits = Number(1234567890.1).toLocaleString(lang, {
useGrouping: false
});
for (var i = 1; i <= 10; i++)
{
var num = i % 10;
var index = i - 1;
numberCharMapByLang[lang][num] = formattedDigits[index];
}
numberCharMapByLang[lang]["."] = formattedDigits[10];
var groupingSeparator = formatted[3];
if (formattedDigits.indexOf(groupingSeparator) !== -1)
formattedDigits = "";
numberCharMapByLang[lang][","] = groupingSeparator;
}
function convertLocal(enValue, lang) {
var value = "";
var map = numberCharMapByLang[lang] || {};
for (var i = 0; i < enValue.length; i++)
{
var c = enValue[i];
value += (c in map) ? map[c] : c;
}
// Update sign if needed
var specs = langSpecs[lang];
if (enValue[0] === "-" && specs.negativePrefix !== "-")
value = specs.negativePrefix + value.substr(1);
if (enValue.substr(0, 2) === "|-" && specs.negativePrefix !== "-")
value = "|" + specs.negativePrefix + value.substr(2);
return value;
}
debug('Arabic number input should accept ASCII digits and Arabic digits, and reject others.');
var input_ar = document.getElementById('input-ar');
shouldBeEqualToString('displayValueForKeyInput(input_ar, "123.4", "", 123.4)', '123.4');
shouldBeEqualToString('displayValueForKeyInput(input_ar, "1.23E+19", "", 12300000000000000000)', '1.23E+19');
shouldBeEqualToString('displayValueForKeyInput(input_ar, "1.23e-1", "", 0.123)', '1.23e-1');
shouldBeEqualToString('displayValueForKeyInput(input_ar, "\u0661\u0669\u0660", "", 190)', '\u0661\u0669\u0660');
shouldBeEqualToString('displayValueForKeyInput(input_ar, "acdef", "", undefined)', 'e');
debug('');
debug('French number input should accept ASCII digits, comma, and full stop.');
var input_fr = document.getElementById('input-fr');
shouldBeEqualToString('displayValueForKeyInput(input_fr, "1234.56", "", 1234.56)', '1234.56');
shouldBeEqualToString('displayValueForKeyInput(input_fr, "1234,56", "", 1234.56)', '1234,56');
debug('');
debug('English number input should accept ASCII digits and full stop, and no comma.');
var input_en = document.getElementById('input-en');
shouldBeEqualToString('displayValueForKeyInput(input_en, "1234.56", "", 1234.56)', '1234.56');
shouldBeEqualToString('displayValueForKeyInput(input_en, "-1234,56", "", -123456)', '-123456');
shouldBeEqualToString('displayValueForKeyInput(input_en, " 1234.56 ", "", 1234.56)', '1234.56');
shouldBeEqualToString('displayValueForKeyInput(input_en, "e", "-1|-1", -0.1)', '-1e-1');
debug('');
debug('Test all locales.');
var tests = [
["123,456,789E+10", "", 1234567890000000000, '123456789E+10'],
[".", "1|e2", 100, '1.e2'],
[".", "1e2|", 100, '1e2'],
[".", "|-12", -12, '-12'],
[".", "|1e-12", 0.0000000000001, '.1e-12'],
["e", "34|12", 34000000000000, '34e12'],
["e", "12|3e4", 1230000, '123e4'],
["e", "123|.4", 123.4, '123.4'],
["e", "12.3|4", 123000, '12.3e4'],
["+", "12|34", undefined, '12+34'],
["+", "-3|4e-12", -0.000000000034, '-34e-12'],
["+", "|1234", 1234, '+1234'],
["-", "123e|4", 0.0123, '123e-4'],
["-", "1|23e4", 1230000, '123e4'],
["-", "123e4|", 1230000, '123e4'],
["9", "|-1", -1, '-1'],
["9", "-|1", -91, '-91'],
["9", "1e|+2", 100, '1e+2'],
["1", "1e+|2", 1000000000000, '1e+12'],
// Invalid
[" abcdef ", "", undefined, 'e'],
["+1-2", "", undefined, '+1-2'],
["+1-2+2-3", "", undefined, '+1-223'],
["0-123-123+123", "", undefined, '0-123-123123'],
["10e123123e1231233e", "", undefined, '10e1231231231233'],
["1e2eee", "", 100, '1e2'],
["1e1e1e", "", 100000000000, '1e11'],
];
for (var test of tests)
{
for (var lang of langs)
{
var specs = langSpecs[lang];
var keyInputs = test[0];
var oldString = test[1];
var expectedNumericValue = test[2];
var expectedStringValue = test[3];
// Build raw new text.
var rawNewText = keyInputs;
if (oldString !== "")
{
var pos = oldString.indexOf("|");
rawNewText = oldString.substr(0, pos) + keyInputs + oldString.substr(pos + 1);
}
// Skip test if there's a comma, but locale doesn't use commas.
// Otherwise, it will be converted to a decimal separator, breaking the expected value.
if (rawNewText.indexOf(",") !== -1 && !specs.usesCommas)
continue;
// Skip test if scientific notation doesn't use "e".
if (rawNewText.toLowerCase().indexOf("e") !== -1 && !specs.usesE)
continue;
// Not uses_single_char_number_filtering_, so build actual value.
if (!specs.usesSingleCharFiltering)
{
// Remove commas.
expectedStringValue = rawNewText.replace(/,/g, "");
// Figure out how this number will parse.
var cleanExpectedStringValue = expectedStringValue.replace(/[^0-9.e+-]/gi, "");
var scientificMatch = /e([+-]?[0-9]+)$/i.exec(cleanExpectedStringValue);
var multiplier = 1;
if (scientificMatch !== null)
{
cleanExpectedStringValue = cleanExpectedStringValue.replace(/e([+-]?[0-9]+)$/gi, "");
multiplier = Math.pow(10, parseInt(scientificMatch[1], 10));
}
expectedNumericValue = Number(cleanExpectedStringValue);
if (isNaN(expectedNumericValue))
expectedNumericValue = undefined;
else
expectedNumericValue *= multiplier;
}
// Skip if a negative number and negative prefix is more than 1 character.
// For ar-eg, Windows seems to strip \u061c when setting the initial text
// causing results to differ.
if (/^\|?-/.test(oldString) && specs.negativePrefixLength > 1)
continue;
// Change to locale if not in scientific notation (and valid).
if (/^[+-]?([0-9]+(\.[0-9]*)|\.[0-9]+)?e[+-]?[0-9]+$/i.exec(expectedStringValue) === null)
{
keyInputs = convertLocal(keyInputs, lang);
oldString = convertLocal(oldString, lang);
expectedStringValue = convertLocal(expectedStringValue, lang);
}
// Skip if it includes the Arabic decimal separator. Windows differs from Mac/Linux.
if (expectedStringValue.indexOf("\u066b") !== -1)
continue;
shouldBeEqualToString('displayValueForKeyInput(input_' + lang.replace(/-.*$/, '') + ', "' + keyInputs + '", "' + oldString + '", ' + expectedNumericValue + ')', expectedStringValue);
}
}
</script>
</body>