From 8a25506957ae24effa9f57c7e4d5571f9e6bc9be Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Tue, 17 Dec 2024 14:50:32 +0100 Subject: [PATCH] [browser] Remove WASM `HybridGlobalization` from runtime code (#110567) * Removal of `HybridGlobalization` code from the runtime and libs. * Remove `HybridGlobalization` flag and clean the tests from it. * Fix build. * Fix build, remove unused leftovers. * Fix linker tests. * Fix the CI error, revert "icudt_hybrid.dat" removal. * Fix WBT that expected `icudt_hybrid.dat` to be missing. --- eng/liveBuilds.targets | 4 +- .../Directory.Build.props | 2 - .../src/Interop/Browser/Interop.Calendar.cs | 14 - .../Interop/Browser/Interop.CompareInfo.cs | 22 -- .../src/Interop/Browser/Interop.Locale.cs | 6 - .../src/Interop/Browser/Interop.TextInfo.cs | 13 - .../ILLink/ILLink.Substitutions.Browser.xml | 10 - .../System.Private.CoreLib.Shared.projitems | 13 - .../Globalization/CalendarData.Browser.cs | 57 --- .../System/Globalization/CalendarData.Unix.cs | 6 +- .../src/System/Globalization/CalendarData.cs | 7 - .../System/Globalization/CompareInfo.Icu.cs | 70 +--- .../Globalization/CompareInfo.WebAssembly.cs | 196 ---------- .../src/System/Globalization/CompareInfo.cs | 27 +- .../Globalization/CultureData.Browser.cs | 61 --- .../src/System/Globalization/CultureData.cs | 24 +- .../src/System/Globalization/DateTimeParse.cs | 16 - .../System/Globalization/GlobalizationMode.cs | 4 +- .../src/System/Globalization/TextInfo.Icu.cs | 3 - .../src/System/Globalization/TextInfo.Nls.cs | 3 - .../Globalization/TextInfo.WebAssembly.cs | 40 -- .../src/System/Globalization/TextInfo.cs | 37 +- src/mono/browser/browser.proj | 6 +- src/mono/browser/build/BrowserWasmApp.targets | 26 +- src/mono/browser/runtime/assets.ts | 14 +- src/mono/browser/runtime/corebindings.c | 22 +- src/mono/browser/runtime/dotnet.d.ts | 14 +- .../browser/runtime/es6/dotnet.es6.lib.js | 3 +- src/mono/browser/runtime/exports-binding.ts | 6 +- src/mono/browser/runtime/exports-linker.ts | 8 +- src/mono/browser/runtime/exports.ts | 16 +- ...ales-common.ts => globalization-locale.ts} | 20 +- .../browser/runtime/globalization-stubs.ts | 69 ---- src/mono/browser/runtime/globalization.ts | 17 +- src/mono/browser/runtime/globals.ts | 4 +- .../runtime/hybrid-globalization/calendar.ts | 364 ------------------ .../hybrid-globalization/change-case.ts | 67 ---- .../hybrid-globalization/collations.ts | 268 ------------- .../hybrid-globalization/culture-info.ts | 139 ------- .../grapheme-segmenter.ts | 142 ------- .../runtime/hybrid-globalization/helpers.ts | 35 -- .../runtime/hybrid-globalization/locales.ts | 89 ----- .../hybrid-globalization/module-exports.ts | 26 -- .../segmentation-rules.json | 83 ---- src/mono/browser/runtime/loader/assets.ts | 22 +- src/mono/browser/runtime/loader/config.ts | 7 - src/mono/browser/runtime/loader/globals.ts | 5 +- src/mono/browser/runtime/loader/icu.ts | 7 +- src/mono/browser/runtime/loader/run.ts | 25 +- src/mono/browser/runtime/rollup.config.js | 15 - src/mono/browser/runtime/types/index.ts | 14 +- src/mono/browser/runtime/types/internal.ts | 19 - ...rosoft.NET.Sdk.WebAssembly.Browser.targets | 16 +- .../WasmFeatures.props | 1 - .../WorkloadTelemetry.targets | 1 - src/mono/sample/wasm/Directory.Build.targets | 2 - .../Common/GlobalizationMode.cs | 1 - .../Wasm.Build.Tests/ProjectProviderBase.cs | 8 - .../WasmSdkBasedProjectProvider.cs | 17 +- src/mono/wasm/build/WasmApp.Common.targets | 1 - .../EntryPoints/HybridGlobalization.cs | 27 -- .../AssetsComputingHelper.cs | 6 - .../BootJsonBuilderHelper.cs | 2 - .../BootJsonData.cs | 5 - .../ComputeWasmBuildAssets.cs | 6 +- .../ComputeWasmPublishAssets.cs | 5 +- .../GenerateWasmBootJson.cs | 4 - src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 7 - .../WasmAppBuilder/WasmAppBuilderBaseTask.cs | 1 - 69 files changed, 79 insertions(+), 2218 deletions(-) delete mode 100644 src/libraries/Common/src/Interop/Browser/Interop.Calendar.cs delete mode 100644 src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs delete mode 100644 src/libraries/Common/src/Interop/Browser/Interop.TextInfo.cs delete mode 100644 src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Browser.xml delete mode 100644 src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Browser.cs delete mode 100644 src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs delete mode 100644 src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.WebAssembly.cs rename src/mono/browser/runtime/{locales-common.ts => globalization-locale.ts} (83%) delete mode 100644 src/mono/browser/runtime/globalization-stubs.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/calendar.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/change-case.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/collations.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/culture-info.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/grapheme-segmenter.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/helpers.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/locales.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/module-exports.ts delete mode 100644 src/mono/browser/runtime/hybrid-globalization/segmentation-rules.json delete mode 100644 src/mono/wasm/testassets/EntryPoints/HybridGlobalization.cs diff --git a/eng/liveBuilds.targets b/eng/liveBuilds.targets index b7c63f1e36b09..01edbff0551fa 100644 --- a/eng/liveBuilds.targets +++ b/eng/liveBuilds.targets @@ -207,15 +207,13 @@ $(LibrariesNativeArtifactsPath)dotnet.js; $(LibrariesNativeArtifactsPath)dotnet.js.map; $(LibrariesNativeArtifactsPath)dotnet.native.js; - $(LibrariesNativeArtifactsPath)dotnet.globalization.js; $(LibrariesNativeArtifactsPath)dotnet.runtime.js; $(LibrariesNativeArtifactsPath)dotnet.runtime.js.map; $(LibrariesNativeArtifactsPath)dotnet.d.ts; $(LibrariesNativeArtifactsPath)package.json; $(LibrariesNativeArtifactsPath)dotnet.native.wasm; $(LibrariesNativeArtifactsPath)dotnet.native.js.symbols; - $(LibrariesNativeArtifactsPath)*.dat; - $(LibrariesNativeArtifactsPath)segmentation-rules.json;" + $(LibrariesNativeArtifactsPath)*.dat;" IsNative="true" /> - @@ -236,7 +235,6 @@ - diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Calendar.cs b/src/libraries/Common/src/Interop/Browser/Interop.Calendar.cs deleted file mode 100644 index 73fbfa924d141..0000000000000 --- a/src/libraries/Common/src/Interop/Browser/Interop.Calendar.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Globalization; -using System.Runtime.CompilerServices; - -internal static partial class Interop -{ - internal static unsafe partial class JsGlobalization - { - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint GetCalendarInfo(char* culture, int cultureLength, CalendarId calendarId, char* buffer, int bufferMaxLength, out int bufferLength); - } -} diff --git a/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs b/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs deleted file mode 100644 index 638934edb416d..0000000000000 --- a/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; - -internal static partial class Interop -{ - internal static unsafe partial class JsGlobalization - { - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint CompareString(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out int resultPtr); - - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint StartsWith(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out bool resultPtr); - - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint EndsWith(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out bool resultPtr); - - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint IndexOf(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, bool fromBeginning, out int resultPtr); - } -} diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Locale.cs b/src/libraries/Common/src/Interop/Browser/Interop.Locale.cs index b2dc0db99c00c..0a2e8449704be 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Locale.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Locale.cs @@ -7,12 +7,6 @@ internal static partial class Interop { internal static unsafe partial class JsGlobalization { - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint GetCultureInfo(char* culture, int cultureLength, char* buffer, int bufferMaxLength, out int resultLength); - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint GetFirstDayOfWeek(char* culture, int cultureLength, out int resultPtr); - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint GetFirstWeekOfYear(char* culture, int cultureLength, out int resultPtr); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern unsafe nint GetLocaleInfo(char* locale, int localeLength, char* culture, int cultureLength, char* buffer, int bufferLength, out int resultLength); } diff --git a/src/libraries/Common/src/Interop/Browser/Interop.TextInfo.cs b/src/libraries/Common/src/Interop/Browser/Interop.TextInfo.cs deleted file mode 100644 index c9a0b3ac39fb4..0000000000000 --- a/src/libraries/Common/src/Interop/Browser/Interop.TextInfo.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; - -internal static partial class Interop -{ - internal static unsafe partial class JsGlobalization - { - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe nint ChangeCase(char* culture, int cultureLen, char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper); - } -} diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Browser.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Browser.xml deleted file mode 100644 index c2e50a979ec7e..0000000000000 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Browser.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 51e003bae50af..2fdf95932689b 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -61,7 +61,6 @@ - @@ -337,7 +336,6 @@ - @@ -351,7 +349,6 @@ - @@ -413,7 +410,6 @@ - @@ -1341,18 +1337,9 @@ - - Common\Interop\Interop.CompareInfo.cs - - - Common\Interop\Interop.Calendar.cs - Common\Interop\Browser\Interop.Locale.cs - - Common\Interop\Interop.TextInfo.cs - Common\Interop\Interop.Calendar.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Browser.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Browser.cs deleted file mode 100644 index 582492c6c40f8..0000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Browser.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - -namespace System.Globalization -{ - internal sealed partial class CalendarData - { - private const int CALENDAR_INFO_BUFFER_LEN = 1000; - private unsafe bool JSLoadCalendarDataFromBrowser(string localeName, CalendarId calendarId) - { - ReadOnlySpan localeNameSpan = localeName.AsSpan(); - fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan)) - { - char* buffer = stackalloc char[CALENDAR_INFO_BUFFER_LEN]; - nint exceptionPtr = Interop.JsGlobalization.GetCalendarInfo(pLocaleName, localeNameSpan.Length, calendarId, buffer, CALENDAR_INFO_BUFFER_LEN, out int resultLength); - Helper.MarshalAndThrowIfException(exceptionPtr); - string result = new string(buffer, 0, resultLength); - string[] subresults = result.Split("##"); - if (subresults.Length < 14) - throw new Exception("CalendarInfo recieved from the Browser is in icorrect format."); - // JS always has one result per locale, so even arrays are initialized with one element - this.sNativeName = string.IsNullOrEmpty(subresults[0]) ? ((CalendarId)calendarId).ToString() : subresults[0]; // this is EnglishName, not NativeName but it's the best we can do - this.saYearMonths = new string[] { subresults[1] }; - this.sMonthDay = subresults[2]; - this.saLongDates = new string[] { subresults[3] }; - this.saShortDates = new string[] { subresults[4] }; - this.saEraNames = new string[] { subresults[5] }; - this.saAbbrevEraNames = new string[] { subresults[6] }; - this.saDayNames = subresults[7].Split("||"); - this.saAbbrevDayNames = subresults[8].Split("||"); - this.saSuperShortDayNames = subresults[9].Split("||"); - this.saMonthNames = ResizeMonthsArray(subresults[10].Split("||")); - this.saAbbrevMonthNames = ResizeMonthsArray(subresults[11].Split("||")); - this.saMonthGenitiveNames = ResizeMonthsArray(subresults[12].Split("||")); - this.saAbbrevMonthGenitiveNames = ResizeMonthsArray(subresults[13].Split("||")); - return true; - } - - static string[] ResizeMonthsArray(string[] months) - { - if (months.Length == 13) - return months; - // most calendars have 12 months and then we expect the 13th month to be empty - string[] resized = new string[13]; - resized[12] = ""; - months.CopyTo(resized, 0); - return resized; - } - } - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Unix.cs index 295a58e9882e1..59785ded51a1e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Unix.cs @@ -9,11 +9,7 @@ internal sealed partial class CalendarData { private bool LoadCalendarDataFromSystemCore(string localeName, CalendarId calendarId) { -#if TARGET_BROWSER - return GlobalizationMode.Hybrid ? - JSLoadCalendarDataFromBrowser(localeName, calendarId) : - IcuLoadCalendarDataFromSystem(localeName, calendarId); -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS return GlobalizationMode.Hybrid ? LoadCalendarDataFromNative(localeName, calendarId) : IcuLoadCalendarDataFromSystem(localeName, calendarId); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.cs index 11b5b69f12922..b4e796126ac29 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.cs @@ -250,13 +250,6 @@ private void InitializeEraNames(string localeName, CalendarId calendarId) break; default: -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid && !AreEraNamesEmpty()) - { - // we don't want to have this overwritten because JS already loaded it - break; - } -#endif // Most calendars are just "A.D." this.saEraNames = Invariant.saEraNames; break; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs index 9b454700f6b3d..35ad3096dbbc9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs @@ -24,7 +24,7 @@ private void IcuInitSortHandle(string interopCultureName) _isAsciiEqualityOrdinal = GetIsAsciiEqualityOrdinal(interopCultureName); if (!GlobalizationMode.Invariant) { -#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS || TARGET_BROWSER +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return; #endif @@ -205,18 +205,7 @@ private unsafe int IndexOfOrdinalIgnoreCaseHelper(ReadOnlySpan source, Rea return -1; InteropCall: -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - ReadOnlySpan cultureNameSpan = m_name.AsSpan(); - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.IndexOf(pCultureName, cultureNameSpan.Length, b, target.Length, a, source.Length, options, fromBeginning, out int result); - Helper.MarshalAndThrowIfException(exceptionPtr); - return result; - } - } -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return IndexOfCoreNative(b, target.Length, a, source.Length, options, fromBeginning, matchLengthPtr); #endif @@ -310,18 +299,7 @@ private unsafe int IndexOfOrdinalHelper(ReadOnlySpan source, ReadOnlySpan< return -1; InteropCall: -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - ReadOnlySpan cultureNameSpan = m_name.AsSpan(); - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.IndexOf(pCultureName, cultureNameSpan.Length, b, target.Length, a, source.Length, options, fromBeginning, out int result); - Helper.MarshalAndThrowIfException(exceptionPtr); - return result; - } - } -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) return IndexOfCoreNative(b, target.Length, a, source.Length, options, fromBeginning, matchLengthPtr); #endif @@ -708,16 +686,6 @@ private unsafe SortKey IcuCreateSortKey(string source, CompareOptions options) Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(!GlobalizationMode.UseNls); -#if TARGET_BROWSER - // JS cannot create locale-sensitive sort key, use invaraint functions instead. - if (GlobalizationMode.Hybrid) - { - if (!_isInvariantCulture) - throw new PlatformNotSupportedException(GetPNSEWithReason("CreateSortKey", "non-invariant culture")); - return InvariantCreateSortKey(source, options); - } -#endif - if ((options & ValidCompareMaskOffFlags) != 0) { throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options)); @@ -776,14 +744,7 @@ private unsafe int IcuGetSortKey(ReadOnlySpan source, Span destinati Debug.Assert(!GlobalizationMode.UseNls); Debug.Assert((options & ValidCompareMaskOffFlags) == 0); -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - if (!_isInvariantCulture) - throw new PlatformNotSupportedException(GetPNSEWithReason("GetSortKey", "non-invariant culture")); - return InvariantGetSortKey(source, destination, options); - } -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { AssertComparisonSupported(options); @@ -832,14 +793,7 @@ private unsafe int IcuGetSortKeyLength(ReadOnlySpan source, CompareOptions Debug.Assert(!GlobalizationMode.UseNls); Debug.Assert((options & ValidCompareMaskOffFlags) == 0); -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - if (!_isInvariantCulture) - throw new PlatformNotSupportedException(GetPNSEWithReason("GetSortKeyLength", "non-invariant culture")); - return InvariantGetSortKeyLength(source, options); - } -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { AssertComparisonSupported(options); @@ -894,19 +848,7 @@ private unsafe int IcuGetHashCodeOfString(ReadOnlySpan source, CompareOpti Debug.Assert(!GlobalizationMode.UseNls); Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - if (!_isInvariantCulture && !LocalizedHashCodeSupportsCompareOptions(options)) - { - throw new PlatformNotSupportedException(GetPNSEWithReason("GetHashCode", "non-invariant culture with CompareOptions different than None or IgnoreCase")); - } - - // JS cannot create locale-sensitive HashCode, use invaraint functions instead - ReadOnlySpan sanitizedSource = SanitizeForInvariantHash(source, options); - return InvariantGetHashCode(sanitizedSource, options); - } -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { AssertComparisonSupported(options); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs deleted file mode 100644 index 26e1116597401..0000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs +++ /dev/null @@ -1,196 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Runtime.InteropServices; - -namespace System.Globalization -{ - public partial class CompareInfo - { - // invariant culture has empty CultureInfo.ToString() and - // m_name == CultureInfo._name == CultureInfo.ToString() - private bool _isInvariantCulture => string.IsNullOrEmpty(m_name); - - private TextInfo? _thisTextInfo; - - private TextInfo thisTextInfo => _thisTextInfo ??= new CultureInfo(m_name).TextInfo; - - private static bool LocalizedHashCodeSupportsCompareOptions(CompareOptions options) => - options == CompareOptions.IgnoreCase || options == CompareOptions.None; - private static void AssertHybridOnWasm(CompareOptions options) - { - Debug.Assert(!GlobalizationMode.Invariant); - Debug.Assert(!GlobalizationMode.UseNls); - Debug.Assert(GlobalizationMode.Hybrid); - Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); - } - - private static void AssertComparisonSupported(CompareOptions options, string cultureName) - { - if (CompareOptionsNotSupported(options)) - throw new PlatformNotSupportedException(GetPNSE(options)); - - if (CompareOptionsNotSupportedForCulture(options, cultureName)) - throw new PlatformNotSupportedException(GetPNSEForCulture(options, cultureName)); - } - - private static void AssertIndexingSupported(CompareOptions options, string cultureName) - { - if (IndexingOptionsNotSupported(options) || CompareOptionsNotSupported(options)) - throw new PlatformNotSupportedException(GetPNSE(options)); - - if (CompareOptionsNotSupportedForCulture(options, cultureName)) - throw new PlatformNotSupportedException(GetPNSEForCulture(options, cultureName)); - } - - private unsafe int JsCompareString(ReadOnlySpan string1, ReadOnlySpan string2, CompareOptions options) - { - AssertHybridOnWasm(options); - AssertComparisonSupported(options, m_name); - - ReadOnlySpan cultureNameSpan = m_name.AsSpan(); - fixed (char* pString1 = &MemoryMarshal.GetReference(string1)) - fixed (char* pString2 = &MemoryMarshal.GetReference(string2)) - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.CompareString(pCultureName, cultureNameSpan.Length, pString1, string1.Length, pString2, string2.Length, options, out int cmpResult); - Helper.MarshalAndThrowIfException(exceptionPtr); - return cmpResult; - } - } - - private unsafe bool JsStartsWith(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options) - { - AssertHybridOnWasm(options); - Debug.Assert(!prefix.IsEmpty); - AssertIndexingSupported(options, m_name); - - ReadOnlySpan cultureNameSpan = m_name.AsSpan(); - fixed (char* pSource = &MemoryMarshal.GetReference(source)) - fixed (char* pPrefix = &MemoryMarshal.GetReference(prefix)) - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.StartsWith(pCultureName, cultureNameSpan.Length, pSource, source.Length, pPrefix, prefix.Length, options, out bool result); - Helper.MarshalAndThrowIfException(exceptionPtr); - return result; - } - } - - private unsafe bool JsEndsWith(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options) - { - AssertHybridOnWasm(options); - Debug.Assert(!prefix.IsEmpty); - AssertIndexingSupported(options, m_name); - - ReadOnlySpan cultureNameSpan = m_name.AsSpan(); - fixed (char* pSource = &MemoryMarshal.GetReference(source)) - fixed (char* pPrefix = &MemoryMarshal.GetReference(prefix)) - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.EndsWith(pCultureName, cultureNameSpan.Length, pSource, source.Length, pPrefix, prefix.Length, options, out bool result); - Helper.MarshalAndThrowIfException(exceptionPtr); - return result; - } - } - - private unsafe int JsIndexOfCore(ReadOnlySpan source, ReadOnlySpan target, CompareOptions options, int* matchLengthPtr, bool fromBeginning) - { - AssertHybridOnWasm(options); - Debug.Assert(!target.IsEmpty); - AssertIndexingSupported(options, m_name); - - if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options)) - { - return (options & CompareOptions.IgnoreCase) != 0 ? - IndexOfOrdinalIgnoreCaseHelper(source, target, options, matchLengthPtr, fromBeginning) : - IndexOfOrdinalHelper(source, target, options, matchLengthPtr, fromBeginning); - } - ReadOnlySpan cultureNameSpan = m_name.AsSpan(); - fixed (char* pSource = &MemoryMarshal.GetReference(source)) - fixed (char* pTarget = &MemoryMarshal.GetReference(target)) - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.IndexOf(pCultureName, cultureNameSpan.Length, pTarget, target.Length, pSource, source.Length, options, fromBeginning, out int idx); - Helper.MarshalAndThrowIfException(exceptionPtr); - return idx; - } - } - - // there are chars that are considered equal by HybridGlobalization but do not have equal hashes when binary hashed - // Control: 1105 (out of 1105) - // Format: 697 (out of 731) - // OtherPunctuation: 6919 (out of 7004) - // SpaceSeparator: 289 (out of 289) - // OpenPunctuation: 1275 (out of 1343) - // ClosePunctuation: 1241 (out of 1309) - // DashPunctuation: 408 (out of 425) - // ConnectorPunctuation: 170 (out of 170) - // InitialQuotePunctuation: 204 (out of 204) - // FinalQuotePunctuation: 170 (out of 170) - // LineSeparator: 17 (out of 17) - // ParagraphSeparator: 17 (out of 17) - // OtherLetter: 34 (out of 784142) - // SpacingCombiningMark: 68 (out of 4420) - // ModifierLetter: 51 (out of 4012) - // EnclosingMark: 85 (out of 221) - // NonSpacingMark: 3281 (out of 18105) - // we can skip them all (~1027k chars) by checking for the remaining UnicodeCategories (~291k chars) - // skipping more characters than ICU would lead to hashes with smaller distribution and more collisions in hash tables - // but it makes the behavior correct and consistent with locale-aware equals, which is acceptable tradeoff - private static bool ShouldNotBeSkipped(UnicodeCategory category) => - category == UnicodeCategory.LowercaseLetter || - category == UnicodeCategory.UppercaseLetter || - category == UnicodeCategory.TitlecaseLetter || - category == UnicodeCategory.LetterNumber || - category == UnicodeCategory.OtherNumber || - category == UnicodeCategory.Surrogate || - category == UnicodeCategory.PrivateUse || - category == UnicodeCategory.MathSymbol || - category == UnicodeCategory.CurrencySymbol || - category == UnicodeCategory.ModifierSymbol || - category == UnicodeCategory.OtherSymbol || - category == UnicodeCategory.OtherNotAssigned; - - private ReadOnlySpan SanitizeForInvariantHash(ReadOnlySpan source, CompareOptions options) - { - char[] result = new char[source.Length]; - int resultIndex = 0; - foreach (char c in source) - { - UnicodeCategory category = CharUnicodeInfo.GetUnicodeCategory(c); - if (ShouldNotBeSkipped(category)) - { - result[resultIndex++] = c; - } - } - if ((options & CompareOptions.IgnoreCase) != 0) - { - string resultStr = new string(result, 0, resultIndex); - // JS-based ToUpper, to keep cases like Turkish I working - resultStr = thisTextInfo.ToUpper(resultStr); - return resultStr.AsSpan(); - } - return result.AsSpan(0, resultIndex); - } - - private static bool IndexingOptionsNotSupported(CompareOptions options) => - (options & (CompareOptions.IgnoreSymbols | CompareOptions.NumericOrdering)) != 0; - - private static bool CompareOptionsNotSupported(CompareOptions options) => - (options & CompareOptions.IgnoreWidth) == CompareOptions.IgnoreWidth || - ((options & CompareOptions.IgnoreNonSpace) == CompareOptions.IgnoreNonSpace && (options & CompareOptions.IgnoreKanaType) == 0); - - private static string GetPNSE(CompareOptions options) => - SR.Format(SR.PlatformNotSupported_HybridGlobalizationWithCompareOptions, options); - - private static bool CompareOptionsNotSupportedForCulture(CompareOptions options, string cultureName) => - ((options & ~CompareOptions.NumericOrdering) == CompareOptions.IgnoreKanaType && - (string.IsNullOrEmpty(cultureName) || cultureName.Split('-')[0] != "ja")) || - ((options & ~CompareOptions.NumericOrdering) == CompareOptions.None && - (cultureName.Split('-')[0] == "ja")); - - private static string GetPNSEForCulture(CompareOptions options, string cultureName) => - SR.Format(SR.PlatformNotSupported_HybridGlobalizationWithCompareOptions, options, cultureName); - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs index dd0b021d3bb05..9c1e6ddee1d2b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs @@ -488,10 +488,7 @@ private static void ThrowCompareOptionsCheckFailed(CompareOptions options) private unsafe int CompareStringCore(ReadOnlySpan string1, ReadOnlySpan string2, CompareOptions options) => GlobalizationMode.UseNls ? NlsCompareString(string1, string2, options) : -#if TARGET_BROWSER - GlobalizationMode.Hybrid ? - JsCompareString(string1, string2, options) : -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS GlobalizationMode.Hybrid ? CompareStringNative(string1, string2, options) : #endif @@ -616,7 +613,7 @@ public unsafe bool IsPrefix(ReadOnlySpan source, ReadOnlySpan prefix else { // Linguistic comparison requested and we don't need to special-case any args. -#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_HybridGlobalizationWithMatchLength); @@ -633,10 +630,6 @@ public unsafe bool IsPrefix(ReadOnlySpan source, ReadOnlySpan prefix private unsafe bool StartsWithCore(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options, int* matchLengthPtr) => GlobalizationMode.UseNls ? NlsStartsWith(source, prefix, options, matchLengthPtr) : -#if TARGET_BROWSER - GlobalizationMode.Hybrid ? - JsStartsWith(source, prefix, options) : -#endif IcuStartsWith(source, prefix, options, matchLengthPtr); public bool IsPrefix(string source, string prefix) @@ -763,7 +756,7 @@ public unsafe bool IsSuffix(ReadOnlySpan source, ReadOnlySpan suffix else { // Linguistic comparison requested and we don't need to special-case any args. -#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_HybridGlobalizationWithMatchLength); @@ -785,10 +778,6 @@ public bool IsSuffix(string source, string suffix) private unsafe bool EndsWithCore(ReadOnlySpan source, ReadOnlySpan suffix, CompareOptions options, int* matchLengthPtr) => GlobalizationMode.UseNls ? NlsEndsWith(source, suffix, options, matchLengthPtr) : -#if TARGET_BROWSER - GlobalizationMode.Hybrid ? - JsEndsWith(source, suffix, options) : -#endif IcuEndsWith(source, suffix, options, matchLengthPtr); /// @@ -1058,7 +1047,7 @@ private unsafe int IndexOf(ReadOnlySpan source, ReadOnlySpan value, { Debug.Assert(matchLengthPtr != null); *matchLengthPtr = 0; -#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_HybridGlobalizationWithMatchLength); @@ -1128,10 +1117,6 @@ private unsafe int IndexOf(ReadOnlySpan source, ReadOnlySpan value, private unsafe int IndexOfCore(ReadOnlySpan source, ReadOnlySpan target, CompareOptions options, int* matchLengthPtr, bool fromBeginning) => GlobalizationMode.UseNls ? NlsIndexOfCore(source, target, options, matchLengthPtr, fromBeginning) : -#if TARGET_BROWSER - GlobalizationMode.Hybrid ? - JsIndexOfCore(source, target, options, matchLengthPtr, fromBeginning) : -#endif IcuIndexOfCore(source, target, options, matchLengthPtr, fromBeginning); /// @@ -1617,7 +1602,7 @@ public SortVersion Version } else { -#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { throw new PlatformNotSupportedException(GetPNSEText("SortVersion")); @@ -1633,7 +1618,7 @@ public SortVersion Version public int LCID => CultureInfo.GetCultureInfo(Name).LCID; -#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS private static string GetPNSEText(string funcName) => SR.Format(SR.PlatformNotSupported_HybridGlobalization, funcName); private static string GetPNSEWithReason(string funcName, string reason) => SR.Format(SR.PlatformNotSupportedWithReason_HybridGlobalization, funcName, reason); #endif diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Browser.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Browser.cs index 897b14e44b3fa..7cf51d7d8f12f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Browser.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Browser.cs @@ -10,7 +10,6 @@ namespace System.Globalization { internal sealed partial class CultureData { - private const int CULTURE_INFO_BUFFER_LEN = 60; private const int LOCALE_INFO_BUFFER_LEN = 80; private void JSInitLocaleInfo() @@ -67,66 +66,6 @@ private string JSGetNativeDisplayName(string localeName, string cultureName) languageName : $"{languageName} ({countryName})"; } - - private static unsafe CultureData JSLoadCultureInfoFromBrowser(string localeName, CultureData culture) - { - ReadOnlySpan localeNameSpan = localeName.AsSpan(); - fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan)) - { - char* buffer = stackalloc char[CULTURE_INFO_BUFFER_LEN]; - nint exceptionPtr = Interop.JsGlobalization.GetCultureInfo(pLocaleName, localeNameSpan.Length, buffer, CULTURE_INFO_BUFFER_LEN, out int resultLength); - Helper.MarshalAndThrowIfException(exceptionPtr); - string result = new string(buffer, 0, resultLength); - string[] subresults = result.Split("##"); - if (subresults.Length < 4) - throw new Exception("CultureInfo recieved from the Browser is in incorrect format."); - culture._sAM1159 = subresults[0]; - culture._sPM2359 = subresults[1]; - culture._saLongTimes = new string[] { subresults[2] }; - culture._saShortTimes = new string[] { subresults[3] }; - } - return culture; - } - - private static unsafe int GetFirstDayOfWeek(string localeName) - { - ReadOnlySpan localeNameSpan = localeName.AsSpan(); - fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.GetFirstDayOfWeek(pLocaleName, localeNameSpan.Length, out int result); - if (exceptionPtr != IntPtr.Zero) - { - int success = Helper.MarshalAndThrowIfException( - exceptionPtr, - failOnlyDebug: true, - failureMessage: $"[CultureData.GetFirstDayOfWeek()] failed with"); - // Failed, just use 0 - if (success == -1) - return 0; - } - return result; - } - } - - private static unsafe int GetFirstWeekOfYear(string localeName) - { - ReadOnlySpan localeNameSpan = localeName.AsSpan(); - fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan)) - { - nint exceptionPtr = Interop.JsGlobalization.GetFirstWeekOfYear(pLocaleName, localeNameSpan.Length, out int result); - if (exceptionPtr != IntPtr.Zero) - { - int success = Helper.MarshalAndThrowIfException( - exceptionPtr, - failOnlyDebug: true, - failureMessage: $"[CultureData.GetFirstWeekOfYear()] failed with"); - // Failed, just use 0 - if (success == -1) - return 0; - } - return result; - } - } } internal static class Helper diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index d6297b5f2e2ce..ecb46a90e1dbb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -815,11 +815,6 @@ private static string NormalizeCultureName(string name, out bool isNeutralName) return null; } #if TARGET_BROWSER - // populate fields for which ICU does not provide data in Hybrid mode - if (GlobalizationMode.Hybrid && !string.IsNullOrEmpty(culture._sName)) - { - culture = JSLoadCultureInfoFromBrowser(culture._sName, culture); - } culture.JSInitLocaleInfo(); #endif @@ -1543,13 +1538,6 @@ internal int FirstDayOfWeek _iFirstDayOfWeek = GetLocaleInfoNative(LocaleNumberData.FirstDayOfWeek); } else -#elif TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - Debug.Assert(_sName != null, "[FirstDayOfWeek] Expected _sName to be populated already"); - _iFirstDayOfWeek = GetFirstDayOfWeek(_sName); - } - else #endif { _iFirstDayOfWeek = ShouldUseUserOverrideNlsData ? NlsGetFirstDayOfWeek() : IcuGetLocaleInfo(LocaleNumberData.FirstDayOfWeek); @@ -1569,17 +1557,7 @@ internal int CalendarWeekRule { if (_iFirstWeekOfYear == undef) { -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - Debug.Assert(_sName != null, "[CalendarWeekRule] Expected _sName to be populated already"); - _iFirstWeekOfYear = GetFirstWeekOfYear(_sName); - } - else -#endif - { - _iFirstWeekOfYear = GetLocaleInfoCoreUserOverride(LocaleNumberData.FirstWeekOfYear); - } + _iFirstWeekOfYear = GetLocaleInfoCoreUserOverride(LocaleNumberData.FirstWeekOfYear); } return _iFirstWeekOfYear; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs index bec15897701aa..4586b81991871 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs @@ -1906,15 +1906,6 @@ private static bool GetDayOfNNY(ref DateTimeResult result, scoped ref DateTimeRa result.flags |= ParseFlags.HaveDate; return true; // MD + Year } -#if TARGET_BROWSER - // if we are parsing the datetime string with custom format then the CultureInfo format `order` - // does not matter and DM + Year is also possible for NNY - if (GlobalizationMode.Hybrid && SetDateYDM(ref result, raw.year, n1, n2)) - { - result.flags |= ParseFlags.HaveDate; - return true; // DM + Year - } -#endif } else { @@ -1923,13 +1914,6 @@ private static bool GetDayOfNNY(ref DateTimeResult result, scoped ref DateTimeRa result.flags |= ParseFlags.HaveDate; return true; // DM + Year } -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid && SetDateYMD(ref result, raw.year, n1, n2)) - { - result.flags |= ParseFlags.HaveDate; - return true; // MD + Year - } -#endif } result.SetBadDateTimeFailure(); return false; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs index 78cebb45b9a00..44a8ed2934686 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs @@ -15,8 +15,6 @@ private static partial class Settings internal static bool Invariant { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.Invariant", "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"); #if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS internal static bool Hybrid { get; } = true; -#elif TARGET_BROWSER - internal static bool Hybrid { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.Hybrid", "DOTNET_SYSTEM_GLOBALIZATION_HYBRID"); #endif internal static bool PredefinedCulturesOnly { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.PredefinedCulturesOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", GlobalizationMode.Invariant); } @@ -40,7 +38,7 @@ internal static bool InvariantNoLoad } } -#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS || TARGET_BROWSER +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS internal static bool Hybrid => Settings.Hybrid; #endif internal static bool PredefinedCulturesOnly => Settings.PredefinedCulturesOnly; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Icu.cs index b2e113cb9c58b..fc7fae4374b8f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Icu.cs @@ -19,9 +19,6 @@ private static bool NeedsTurkishCasing(string localeName) internal unsafe void IcuChangeCase(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper) { Debug.Assert(!GlobalizationMode.Invariant); -#if TARGET_BROWSER - Debug.Assert(!GlobalizationMode.Hybrid); -#endif Debug.Assert(!GlobalizationMode.UseNls); if (HasEmptyCultureName) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Nls.cs index 57c47cf9a9812..ca6689f4cef53 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Nls.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Nls.cs @@ -10,9 +10,6 @@ public partial class TextInfo private unsafe void NlsChangeCase(char* pSource, int pSourceLen, char* pResult, int pResultLen, bool toUpper) { Debug.Assert(!GlobalizationMode.Invariant); -#if TARGET_BROWSER - Debug.Assert(!GlobalizationMode.Hybrid); -#endif Debug.Assert(GlobalizationMode.UseNls); Debug.Assert(pSource != null); Debug.Assert(pResult != null); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.WebAssembly.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.WebAssembly.cs deleted file mode 100644 index 459478f705504..0000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.WebAssembly.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Runtime.InteropServices; - -namespace System.Globalization -{ - public partial class TextInfo - { - internal unsafe void JsChangeCase(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool toUpper) - { - Debug.Assert(!GlobalizationMode.Invariant); - Debug.Assert(!GlobalizationMode.UseNls); - Debug.Assert(GlobalizationMode.Hybrid); - - if (HasEmptyCultureName) - { - ReadOnlySpan source = new ReadOnlySpan(src, srcLen); - Span destination = new Span(dstBuffer, dstBufferCapacity); - if (toUpper) - { - InvariantModeCasing.ToUpper(source, destination); - } - else - { - InvariantModeCasing.ToLower(source, destination); - } - return; - } - - ReadOnlySpan cultureName = _cultureName.AsSpan(); - fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureName)) - { - nint exceptionPtr = Interop.JsGlobalization.ChangeCase(pCultureName, cultureName.Length, src, srcLen, dstBuffer, dstBufferCapacity, toUpper); - Helper.MarshalAndThrowIfException(exceptionPtr); - } - } - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs index 45123f85d4341..5b6f26637dcac 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs @@ -140,12 +140,7 @@ public string ListSeparator /// public char ToLower(char c) { -#if TARGET_BROWSER - // for invariant culture _cultureName is empty - HybridGlobalization does not have to call JS - if (GlobalizationMode.Invariant || (GlobalizationMode.Hybrid && HasEmptyCultureName)) -#else if (GlobalizationMode.Invariant) -#endif { return InvariantModeCasing.ToLower(c); } @@ -178,12 +173,7 @@ public string ToLower(string str) { ArgumentNullException.ThrowIfNull(str); -#if TARGET_BROWSER - // for invariant culture _cultureName is empty - HybridGlobalization does not have to call JS - if (GlobalizationMode.Invariant || (GlobalizationMode.Hybrid && HasEmptyCultureName)) -#else if (GlobalizationMode.Invariant) -#endif { return InvariantModeCasing.ToLower(str); } @@ -194,9 +184,6 @@ public string ToLower(string str) private unsafe char ChangeCase(char c, bool toUpper) { Debug.Assert(!GlobalizationMode.Invariant); -#if TARGET_BROWSER - Debug.Assert(!(GlobalizationMode.Hybrid && HasEmptyCultureName)); -#endif char dst = default; ChangeCaseCore(&c, 1, &dst, 1, toUpper); return dst; @@ -239,9 +226,6 @@ private unsafe void ChangeCaseCommon(ReadOnlySpan source, Spa { Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(typeof(TConversion) == typeof(ToUpperConversion) || typeof(TConversion) == typeof(ToLowerConversion)); -#if TARGET_BROWSER - Debug.Assert(!(GlobalizationMode.Hybrid && HasEmptyCultureName)); -#endif if (source.IsEmpty) { @@ -278,9 +262,6 @@ private unsafe string ChangeCaseCommon(string source) where TConver Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(source != null); -#if TARGET_BROWSER - Debug.Assert(!(GlobalizationMode.Hybrid && HasEmptyCultureName)); -#endif // If the string is empty, we're done. if (source.Length == 0) @@ -430,12 +411,7 @@ private static char ToLowerAsciiInvariant(char c) /// public char ToUpper(char c) { -#if TARGET_BROWSER - // for invariant culture _cultureName is empty - HybridGlobalization does not have to call JS - if (GlobalizationMode.Invariant || (GlobalizationMode.Hybrid && HasEmptyCultureName)) -#else if (GlobalizationMode.Invariant) -#endif { return InvariantModeCasing.ToUpper(c); } @@ -468,12 +444,7 @@ public string ToUpper(string str) { ArgumentNullException.ThrowIfNull(str); -#if TARGET_BROWSER - // for invariant culture _cultureName is empty - HybridGlobalization does not have to call JS - if (GlobalizationMode.Invariant || (GlobalizationMode.Hybrid && HasEmptyCultureName)) -#else if (GlobalizationMode.Invariant) -#endif { return InvariantModeCasing.ToUpper(str); } @@ -732,13 +703,7 @@ private unsafe void ChangeCaseCore(char* src, int srcLen, char* dstBuffer, int d NlsChangeCase(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper); return; } -#if TARGET_BROWSER - if (GlobalizationMode.Hybrid) - { - JsChangeCase(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper); - return; - } -#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) { ChangeCaseNative(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper); diff --git a/src/mono/browser/browser.proj b/src/mono/browser/browser.proj index 88a0afb3bf91e..d09d7f7021484 100644 --- a/src/mono/browser/browser.proj +++ b/src/mono/browser/browser.proj @@ -378,8 +378,7 @@ + $(ICULibDir)/libicudata.a" /> @@ -502,8 +501,7 @@ $(NativeBinDir)dotnet.native.js; $(NativeBinDir)dotnet.d.ts; $(NativeBinDir)package.json; - $(NativeBinDir)dotnet.native.wasm; - $(NativeBinDir)dotnet.globalization.js" + $(NativeBinDir)dotnet.native.wasm;" DestinationFolder="$(MicrosoftNetCoreAppRuntimePackNativeDir)" SkipUnchangedFiles="true" /> diff --git a/src/mono/browser/build/BrowserWasmApp.targets b/src/mono/browser/build/BrowserWasmApp.targets index 728c600a74022..2e611016df020 100644 --- a/src/mono/browser/build/BrowserWasmApp.targets +++ b/src/mono/browser/build/BrowserWasmApp.targets @@ -73,8 +73,6 @@ - - @@ -82,10 +80,8 @@ <_HasDotnetJsWorker Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.native.worker.mjs'">true <_HasDotnetJsSymbols Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.native.js.symbols'">true <_HasDotnetNativeJs Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.native.js'">true - <_HasDotnetGlobalizationJs Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.globalization.js'">true - false - <_WasmIcuDataFileName Condition="'$(HybridGlobalization)' != 'true' and '$(WasmIcuDataFileName)' != '' and Exists('$(WasmIcuDataFileName)')">$(WasmIcuDataFileName) - <_WasmIcuDataFileName Condition="'$(HybridGlobalization)' != 'true' and '$(WasmIcuDataFileName)' != '' and !Exists('$(WasmIcuDataFileName)')">$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(WasmIcuDataFileName) + <_WasmIcuDataFileName Condition="'$(WasmIcuDataFileName)' != '' and Exists('$(WasmIcuDataFileName)')">$(WasmIcuDataFileName) + <_WasmIcuDataFileName Condition="'$(WasmIcuDataFileName)' != '' and !Exists('$(WasmIcuDataFileName)')">$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(WasmIcuDataFileName) @@ -95,10 +91,6 @@ - - <_HybridGlobalizationDataFiles Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)icudt_hybrid.dat"/> - <_HybridGlobalizationDataFiles Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)segmentation-rules.json"/> - <_IcuAvailableDataFiles Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)icudt_*" Exclude="@(_HybridGlobalizationDataFiles);$(_WasmIcuDataFileName)"/> - - - - + <_IcuAvailableDataFiles Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)icudt_*" Exclude="$(_WasmIcuDataFileName)"/> + + + @@ -150,7 +139,6 @@ RuntimeArgsForHost="@(WasmMonoRuntimeArgs)" DefaultHostConfig="$(DefaultWasmHostConfig)" InvariantGlobalization="$(InvariantGlobalization)" - HybridGlobalization="$(HybridGlobalization)" SatelliteAssemblies="@(_WasmSatelliteAssemblies)" FilesToIncludeInFileSystem="@(WasmFilesToIncludeInFileSystem)" IcuDataFileNames="@(WasmIcuDataFileNames)" @@ -508,7 +496,6 @@ - @@ -564,7 +551,6 @@ - <_WasmAssembliesInternal Remove="$(_WasmDedupAssembly)"/> diff --git a/src/mono/browser/runtime/assets.ts b/src/mono/browser/runtime/assets.ts index 930f5bb20d184..9c5290a08f14e 100644 --- a/src/mono/browser/runtime/assets.ts +++ b/src/mono/browser/runtime/assets.ts @@ -5,7 +5,7 @@ import type { AssetEntryInternal } from "./types/internal"; import cwraps from "./cwraps"; import { mono_wasm_load_icu_data } from "./icu"; -import { Module, globalizationHelpers, loaderHelpers, mono_assert, runtimeHelpers } from "./globals"; +import { Module, loaderHelpers, mono_assert, runtimeHelpers } from "./globals"; import { mono_log_info, mono_log_debug, parseSymbolMapFile } from "./logging"; import { mono_wasm_load_bytes_into_heap_persistent } from "./memory"; import { endMeasure, MeasuredBlock, startMeasure } from "./profiler"; @@ -25,9 +25,7 @@ export function instantiate_asset (asset: AssetEntry, url: string, bytes: Uint8A switch (asset.behavior) { case "dotnetwasm": case "js-module-threads": - case "js-module-globalization": case "symbols": - case "segmentation-rules": // do nothing break; case "resource": @@ -106,16 +104,6 @@ export async function instantiate_symbols_asset (pendingAsset: AssetEntryInterna } } -export async function instantiate_segmentation_rules_asset (pendingAsset: AssetEntryInternal): Promise { - try { - const response = await pendingAsset.pendingDownloadInternal!.response; - const json = await response.json(); - globalizationHelpers.setSegmentationRulesFromJson(json); - } catch (error: any) { - mono_log_info(`Error loading static json asset ${pendingAsset.name}: ${JSON.stringify(error)}`); - } -} - export async function wait_for_all_assets () { // wait for all assets in memory await runtimeHelpers.allAssetsInMemory.promise; diff --git a/src/mono/browser/runtime/corebindings.c b/src/mono/browser/runtime/corebindings.c index 15a185133ce36..e64c5f6d2d81a 100644 --- a/src/mono/browser/runtime/corebindings.c +++ b/src/mono/browser/runtime/corebindings.c @@ -58,17 +58,8 @@ extern void* mono_wasm_bind_js_import_ST (void *signature); extern void mono_wasm_invoke_jsimport_ST (int function_handle, void *args); #endif /* DISABLE_THREADS */ -// HybridGlobalization -extern char16_t* mono_wasm_change_case (const uint16_t* culture, int32_t cultureLength, const uint16_t* src, int32_t srcLength, uint16_t* dst, int32_t dstLength, mono_bool bToUpper); -extern char16_t* mono_wasm_compare_string (const uint16_t* culture, int32_t cultureLength, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, int *resultPtr); -extern char16_t* mono_wasm_starts_with (const uint16_t* culture, int32_t cultureLength, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, mono_bool *resultPtr); -extern char16_t* mono_wasm_ends_with (const uint16_t* culture, int32_t cultureLength, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, mono_bool *resultPtr); -extern char16_t* mono_wasm_index_of (const uint16_t* culture, int32_t cultureLength, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, mono_bool fromBeginning, int *resultPtr); -extern char16_t* mono_wasm_get_calendar_info (const uint16_t* culture, int32_t cultureLength, int32_t calendarId, const uint16_t* result, int32_t resultMaxLength, int *resultLength); -extern char16_t* mono_wasm_get_culture_info (const uint16_t* culture, int32_t cultureLength, const uint16_t* result, int32_t resultMaxLength, int *resultLength); +// JS-based globalization extern char16_t* mono_wasm_get_locale_info (const uint16_t* locale, int32_t localeLength, const uint16_t* culture, int32_t cultureLength, const uint16_t* result, int32_t resultMaxLength, int *resultLength); -extern char16_t* mono_wasm_get_first_day_of_week (const uint16_t* culture, int32_t cultureLength, int *resultPtr); -extern char16_t* mono_wasm_get_first_week_of_year (const uint16_t* culture, int32_t cultureLength, int *resultPtr); void bindings_initialize_internals (void) { @@ -102,17 +93,8 @@ void bindings_initialize_internals (void) mono_add_internal_call ("Interop/Runtime::GetAssemblyExport", mono_wasm_get_assembly_export); mono_add_internal_call ("System.ConsolePal::Clear", mono_wasm_console_clear); - // HybridGlobalization - mono_add_internal_call ("Interop/JsGlobalization::ChangeCase", mono_wasm_change_case); - mono_add_internal_call ("Interop/JsGlobalization::CompareString", mono_wasm_compare_string); - mono_add_internal_call ("Interop/JsGlobalization::StartsWith", mono_wasm_starts_with); - mono_add_internal_call ("Interop/JsGlobalization::EndsWith", mono_wasm_ends_with); - mono_add_internal_call ("Interop/JsGlobalization::IndexOf", mono_wasm_index_of); - mono_add_internal_call ("Interop/JsGlobalization::GetCalendarInfo", mono_wasm_get_calendar_info); + // JS-based globalization mono_add_internal_call ("Interop/JsGlobalization::GetLocaleInfo", mono_wasm_get_locale_info); - mono_add_internal_call ("Interop/JsGlobalization::GetCultureInfo", mono_wasm_get_culture_info); - mono_add_internal_call ("Interop/JsGlobalization::GetFirstDayOfWeek", mono_wasm_get_first_day_of_week); - mono_add_internal_call ("Interop/JsGlobalization::GetFirstWeekOfYear", mono_wasm_get_first_week_of_year); } static MonoAssembly* _mono_wasm_assembly_load (char *assembly_name) diff --git a/src/mono/browser/runtime/dotnet.d.ts b/src/mono/browser/runtime/dotnet.d.ts index 01218688846cb..5bff371447de0 100644 --- a/src/mono/browser/runtime/dotnet.d.ts +++ b/src/mono/browser/runtime/dotnet.d.ts @@ -368,10 +368,6 @@ type SingleAssetBehaviors = * The javascript module for emscripten. */ | "js-module-native" -/** - * The javascript module for hybrid globalization. - */ - | "js-module-globalization" /** * Typically blazor.boot.json */ @@ -380,10 +376,6 @@ type SingleAssetBehaviors = * The debugging symbols */ | "symbols" -/** - * Load segmentation rules file for Hybrid Globalization. - */ - | "segmentation-rules"; type AssetBehaviors = SingleAssetBehaviors | /** * Load asset as a managed resource assembly. @@ -429,11 +421,7 @@ declare const enum GlobalizationMode { /** * Use user defined icu file. */ - Custom = "custom", - /** - * Operate in hybrid globalization mode with small ICU files, using native platform functions. - */ - Hybrid = "hybrid" + Custom = "custom" } type DotnetModuleConfig = { config?: MonoConfig; diff --git a/src/mono/browser/runtime/es6/dotnet.es6.lib.js b/src/mono/browser/runtime/es6/dotnet.es6.lib.js index 687025478570e..ad8b0303bbb12 100644 --- a/src/mono/browser/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/browser/runtime/es6/dotnet.es6.lib.js @@ -77,8 +77,7 @@ function createWasmImportStubsFrom(collection) { // we will replace them with the real implementation in replace_linker_placeholders function injectDependencies() { createWasmImportStubsFrom(methodIndexByName.mono_wasm_imports); - // mono_wasm_hybrid_globalization_imports is empty in non-hybrid globalization mode - createWasmImportStubsFrom(methodIndexByName.mono_wasm_hybrid_globalization_imports); + createWasmImportStubsFrom(methodIndexByName.mono_wasm_js_globalization_imports); #if USE_PTHREADS createWasmImportStubsFrom(methodIndexByName.mono_wasm_threads_imports); diff --git a/src/mono/browser/runtime/exports-binding.ts b/src/mono/browser/runtime/exports-binding.ts index 6ae7a08b95b0b..5e7472f0a2dea 100644 --- a/src/mono/browser/runtime/exports-binding.ts +++ b/src/mono/browser/runtime/exports-binding.ts @@ -27,7 +27,7 @@ import { } from "./pthreads"; import { mono_wasm_dump_threads } from "./pthreads/ui-thread"; import { mono_wasm_schedule_synchronization_context } from "./pthreads/shared"; -import { mono_wasm_hybrid_globalization_imports } from "./globalization"; +import { mono_wasm_js_globalization_imports } from "./globalization"; // the JS methods would be visible to EMCC linker and become imports of the WASM module @@ -103,8 +103,8 @@ const wasmImports: Function[] = [ ...mono_wasm_imports, // threading exports, if threading is enabled ...mono_wasm_threads_imports, - // hybrid globalization exports - ...mono_wasm_hybrid_globalization_imports, + // globalization exports + ...mono_wasm_js_globalization_imports, ]; export function replace_linker_placeholders (imports: WebAssembly.Imports) { diff --git a/src/mono/browser/runtime/exports-linker.ts b/src/mono/browser/runtime/exports-linker.ts index 3e1f8c4bd99c7..6eda7b34ae1b8 100644 --- a/src/mono/browser/runtime/exports-linker.ts +++ b/src/mono/browser/runtime/exports-linker.ts @@ -3,13 +3,13 @@ import { mono_wasm_imports, mono_wasm_threads_imports } from "./exports-binding"; import gitHash from "consts:gitHash"; -import { mono_wasm_hybrid_globalization_imports } from "./globalization"; +import { mono_wasm_js_globalization_imports } from "./globalization"; export function export_linker_indexes_as_code (): string { const indexByName: any = { mono_wasm_imports: {}, mono_wasm_threads_imports: {}, - mono_wasm_hybrid_globalization_imports: {}, + mono_wasm_js_globalization_imports: {}, }; let idx = 0; for (const wi of mono_wasm_imports) { @@ -20,8 +20,8 @@ export function export_linker_indexes_as_code (): string { indexByName.mono_wasm_threads_imports[wi.name] = idx; idx++; } - for (const wi of mono_wasm_hybrid_globalization_imports) { - indexByName.mono_wasm_hybrid_globalization_imports[wi.name] = idx; + for (const wi of mono_wasm_js_globalization_imports) { + indexByName.mono_wasm_js_globalization_imports[wi.name] = idx; idx++; } return ` diff --git a/src/mono/browser/runtime/exports.ts b/src/mono/browser/runtime/exports.ts index 6c2b1fd106596..23d6d30e28800 100644 --- a/src/mono/browser/runtime/exports.ts +++ b/src/mono/browser/runtime/exports.ts @@ -7,7 +7,7 @@ import WasmEnableThreads from "consts:wasmEnableThreads"; import WasmEnableSIMD from "consts:wasmEnableSIMD"; import WasmEnableExceptionHandling from "consts:wasmEnableExceptionHandling"; -import { GlobalizationMode, type RuntimeAPI } from "./types"; +import { type RuntimeAPI } from "./types"; import { Module, exportedRuntimeAPI, loaderHelpers, passEmscriptenInternals, runtimeHelpers, setRuntimeGlobals, } from "./globals"; import { GlobalObjects, RuntimeHelpers } from "./types/internal"; @@ -19,14 +19,12 @@ import { export_api } from "./export-api"; import { initializeReplacements } from "./polyfills"; import { mono_wasm_stringify_as_error_with_stack } from "./logging"; -import { instantiate_asset, instantiate_symbols_asset, instantiate_segmentation_rules_asset } from "./assets"; +import { instantiate_asset, instantiate_symbols_asset } from "./assets"; import { jiterpreter_dump_stats } from "./jiterpreter"; import { forceDisposeProxies } from "./gc-handles"; import { mono_wasm_dump_threads } from "./pthreads"; import { threads_c_functions as tcwraps } from "./cwraps"; -import { stringToUTF16, stringToUTF16Ptr, utf16ToString, utf16ToStringLoop } from "./strings"; -import { localHeapViewU16, setI32, setU16_local } from "./memory"; export let runtimeList: RuntimeList; @@ -42,22 +40,12 @@ function initializeExports (globalObjects: GlobalObjects): RuntimeAPI { instantiate_asset, jiterpreter_dump_stats, forceDisposeProxies, - instantiate_segmentation_rules_asset, }; if (WasmEnableThreads) { rh.dumpThreads = mono_wasm_dump_threads; rh.mono_wasm_print_thread_dump = () => tcwraps.mono_wasm_print_thread_dump(); } - if (loaderHelpers.config.globalizationMode === GlobalizationMode.Hybrid) { - rh.stringToUTF16 = stringToUTF16; - rh.stringToUTF16Ptr = stringToUTF16Ptr; - rh.utf16ToString = utf16ToString; - rh.utf16ToStringLoop = utf16ToStringLoop; - rh.localHeapViewU16 = localHeapViewU16; - rh.setU16_local = setU16_local; - rh.setI32 = setI32; - } Object.assign(runtimeHelpers, rh); diff --git a/src/mono/browser/runtime/locales-common.ts b/src/mono/browser/runtime/globalization-locale.ts similarity index 83% rename from src/mono/browser/runtime/locales-common.ts rename to src/mono/browser/runtime/globalization-locale.ts index aa3a8ce6c919e..1b95edfb6878a 100644 --- a/src/mono/browser/runtime/locales-common.ts +++ b/src/mono/browser/runtime/globalization-locale.ts @@ -3,11 +3,27 @@ import { VoidPtrNull } from "./types/internal"; import { Int32Ptr, VoidPtr } from "./types/emscripten"; -import { OUTER_SEPARATOR, normalizeLocale } from "./hybrid-globalization/helpers"; import { stringToUTF16, stringToUTF16Ptr, utf16ToString } from "./strings"; import { setI32 } from "./memory"; -// functions common for Hybrid Globalization -> true | false : +export const OUTER_SEPARATOR = "##"; + +function normalizeLocale (locale: string | null) { + if (!locale) + return undefined; + try { + locale = locale.toLocaleLowerCase(); + if (locale.includes("zh")) { + // browser does not recognize "zh-chs" and "zh-cht" as equivalents of "zh-HANS" "zh-HANT", we are helping, otherwise + // it would throw on getCanonicalLocales with "RangeError: Incorrect locale information provided" + locale = locale.replace("chs", "HANS").replace("cht", "HANT"); + } + const canonicalLocales = (Intl as any).getCanonicalLocales(locale.replace("_", "-")); + return canonicalLocales.length > 0 ? canonicalLocales[0] : undefined; + } catch { + return undefined; + } +} export function mono_wasm_get_locale_info (culture: number, cultureLength: number, locale: number, localeLength: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr { try { diff --git a/src/mono/browser/runtime/globalization-stubs.ts b/src/mono/browser/runtime/globalization-stubs.ts deleted file mode 100644 index a1a42dc1cd414..0000000000000 --- a/src/mono/browser/runtime/globalization-stubs.ts +++ /dev/null @@ -1,69 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { globalizationHelpers } from "./globals"; -import { Int32Ptr, VoidPtr } from "./types/emscripten"; -import { VoidPtrNull } from "./types/internal"; - -export function mono_wasm_change_case (culture: number, cultureLength: number, src: number, srcLength: number, dst: number, dstLength: number, toUpper: number) : VoidPtr { - if (typeof globalizationHelpers.mono_wasm_change_case === "function") { - return globalizationHelpers.mono_wasm_change_case(culture, cultureLength, src, srcLength, dst, dstLength, toUpper); - } - return VoidPtrNull; -} - -export function mono_wasm_compare_string (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr) : VoidPtr { - if (typeof globalizationHelpers.mono_wasm_compare_string === "function") { - return globalizationHelpers.mono_wasm_compare_string(culture, cultureLength, str1, str1Length, str2, str2Length, options, resultPtr); - } - return VoidPtrNull; -} - -export function mono_wasm_starts_with (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_starts_with === "function") { - return globalizationHelpers.mono_wasm_starts_with(culture, cultureLength, str1, str1Length, str2, str2Length, options, resultPtr); - } - return VoidPtrNull; -} - -export function mono_wasm_ends_with (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_ends_with === "function") { - return globalizationHelpers.mono_wasm_ends_with(culture, cultureLength, str1, str1Length, str2, str2Length, options, resultPtr); - } - return VoidPtrNull; -} - -export function mono_wasm_index_of (culture: number, cultureLength: number, needlePtr: number, needleLength: number, srcPtr: number, srcLength: number, options: number, fromBeginning: number, resultPtr: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_index_of === "function") { - return globalizationHelpers.mono_wasm_index_of(culture, cultureLength, needlePtr, needleLength, srcPtr, srcLength, options, fromBeginning, resultPtr); - } - return VoidPtrNull; -} - -export function mono_wasm_get_calendar_info (culture: number, cultureLength: number, calendarId: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_get_calendar_info === "function") { - return globalizationHelpers.mono_wasm_get_calendar_info(culture, cultureLength, calendarId, dst, dstMaxLength, dstLength); - } - return VoidPtrNull; -} - -export function mono_wasm_get_culture_info (culture: number, cultureLength: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_get_culture_info === "function") { - return globalizationHelpers.mono_wasm_get_culture_info(culture, cultureLength, dst, dstMaxLength, dstLength); - } - return VoidPtrNull; -} - -export function mono_wasm_get_first_day_of_week (culture: number, cultureLength: number, resultPtr: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_get_first_day_of_week === "function") { - return globalizationHelpers.mono_wasm_get_first_day_of_week(culture, cultureLength, resultPtr); - } - return VoidPtrNull; -} - -export function mono_wasm_get_first_week_of_year (culture: number, cultureLength: number, resultPtr: Int32Ptr): VoidPtr { - if (typeof globalizationHelpers.mono_wasm_get_first_week_of_year === "function") { - return globalizationHelpers.mono_wasm_get_first_week_of_year(culture, cultureLength, resultPtr); - } - return VoidPtrNull; -} diff --git a/src/mono/browser/runtime/globalization.ts b/src/mono/browser/runtime/globalization.ts index fe1b95be3ba73..c7fb8eeafce9d 100644 --- a/src/mono/browser/runtime/globalization.ts +++ b/src/mono/browser/runtime/globalization.ts @@ -1,19 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { mono_wasm_change_case, mono_wasm_compare_string, mono_wasm_ends_with, mono_wasm_get_calendar_info, mono_wasm_get_culture_info, mono_wasm_get_first_day_of_week, mono_wasm_get_first_week_of_year, mono_wasm_index_of, mono_wasm_starts_with } from "./globalization-stubs"; -import { mono_wasm_get_locale_info } from "./locales-common"; +import { mono_wasm_get_locale_info } from "./globalization-locale"; -export const mono_wasm_hybrid_globalization_imports = [ - mono_wasm_change_case, - mono_wasm_compare_string, - mono_wasm_starts_with, - mono_wasm_ends_with, - mono_wasm_index_of, - mono_wasm_get_calendar_info, - mono_wasm_get_culture_info, - mono_wasm_get_first_day_of_week, - mono_wasm_get_first_week_of_year, - // used by both: non-HG and HG: +// JS-based globalization support for WebAssembly + +export const mono_wasm_js_globalization_imports = [ mono_wasm_get_locale_info, ]; diff --git a/src/mono/browser/runtime/globals.ts b/src/mono/browser/runtime/globals.ts index f6b8aa1f548f9..e1eeed5ddce1d 100644 --- a/src/mono/browser/runtime/globals.ts +++ b/src/mono/browser/runtime/globals.ts @@ -9,7 +9,7 @@ import gitHash from "consts:gitHash"; import { RuntimeAPI } from "./types/index"; -import type { GlobalObjects, EmscriptenInternals, RuntimeHelpers, LoaderHelpers, DotnetModuleInternal, PromiseAndController, EmscriptenBuildOptions, GCHandle, GlobalizationHelpers } from "./types/internal"; +import type { GlobalObjects, EmscriptenInternals, RuntimeHelpers, LoaderHelpers, DotnetModuleInternal, PromiseAndController, EmscriptenBuildOptions, GCHandle } from "./types/internal"; import { mono_log_error } from "./logging"; // these are our public API (except internal) @@ -29,7 +29,6 @@ export let ENVIRONMENT_IS_PTHREAD: boolean; export let exportedRuntimeAPI: RuntimeAPI = null as any; export let runtimeHelpers: RuntimeHelpers = null as any; export let loaderHelpers: LoaderHelpers = null as any; -export let globalizationHelpers: GlobalizationHelpers = null as any; export let _runtimeModuleLoaded = false; // please keep it in place also as rollup guard @@ -54,7 +53,6 @@ export function setRuntimeGlobals (globalObjects: GlobalObjects) { INTERNAL = globalObjects.internal; runtimeHelpers = globalObjects.runtimeHelpers; loaderHelpers = globalObjects.loaderHelpers; - globalizationHelpers = globalObjects.globalizationHelpers; exportedRuntimeAPI = globalObjects.api; const rh: Partial = { diff --git a/src/mono/browser/runtime/hybrid-globalization/calendar.ts b/src/mono/browser/runtime/hybrid-globalization/calendar.ts deleted file mode 100644 index fd211755469d3..0000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/calendar.ts +++ /dev/null @@ -1,364 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/* eslint-disable no-inner-declarations */ -import { VoidPtrNull } from "../types/internal"; -import { runtimeHelpers } from "./module-exports"; -import { Int32Ptr, VoidPtr } from "../types/emscripten"; -import { INNER_SEPARATOR, OUTER_SEPARATOR } from "./helpers"; - -const MONTH_CODE = "MMMM"; -const YEAR_CODE = "yyyy"; -const DAY_CODE = "d"; -const WEEKDAY_CODE = "dddd"; -const keyWords = [MONTH_CODE, YEAR_CODE, DAY_CODE, WEEKDAY_CODE]; - -// this function joins all calendar info with OUTER_SEPARATOR into one string and returns it back to managed code -export function mono_wasm_get_calendar_info (culture: number, cultureLength: number, calendarId: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const locale = cultureName ? cultureName : undefined; - const calendarInfo = { - EnglishName: "", - YearMonth: "", - MonthDay: "", - LongDates: "", - ShortDates: "", - EraNames: "", - AbbreviatedEraNames: "", - DayNames: "", - AbbreviatedDayNames: "", - ShortestDayNames: "", - MonthNames: "", - AbbreviatedMonthNames: "", - MonthGenitiveNames: "", - AbbrevMonthGenitiveNames: "", - }; - const date = new Date(999, 10, 22); // Fri Nov 22 0999 00:00:00 GMT+0124 (Central European Standard Time) - calendarInfo.EnglishName = getCalendarName(locale); - const dayNames = getDayNames(locale); - calendarInfo.DayNames = dayNames.long.join(INNER_SEPARATOR); - calendarInfo.AbbreviatedDayNames = dayNames.abbreviated.join(INNER_SEPARATOR); - calendarInfo.ShortestDayNames = dayNames.shortest.join(INNER_SEPARATOR); - const monthNames = getMonthNames(locale); - calendarInfo.MonthNames = monthNames.long.join(INNER_SEPARATOR); - calendarInfo.AbbreviatedMonthNames = monthNames.abbreviated.join(INNER_SEPARATOR); - calendarInfo.MonthGenitiveNames = monthNames.longGenitive.join(INNER_SEPARATOR); - calendarInfo.AbbrevMonthGenitiveNames = monthNames.abbreviatedGenitive.join(INNER_SEPARATOR); - calendarInfo.YearMonth = getMonthYearPattern(locale, date); - calendarInfo.MonthDay = getMonthDayPattern(locale, date); - calendarInfo.ShortDates = getShortDatePattern(locale); - calendarInfo.LongDates = getLongDatePattern(locale, date); - const eraNames = getEraNames(date, locale, calendarId); - calendarInfo.EraNames = eraNames.eraNames; - calendarInfo.AbbreviatedEraNames = eraNames.abbreviatedEraNames; - - const result = Object.values(calendarInfo).join(OUTER_SEPARATOR); - if (result.length > dstMaxLength) { - throw new Error(`Calendar info exceeds length of ${dstMaxLength}.`); - } - runtimeHelpers.stringToUTF16(dst, dst + 2 * result.length, result); - runtimeHelpers.setI32(dstLength, result.length); - return VoidPtrNull; - } catch (ex: any) { - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -function getCalendarName (locale: any) { - const calendars = getCalendarInfo(locale); - if (!calendars || calendars.length == 0) - return ""; - return calendars[0]; -} - -function getCalendarInfo (locale: string) { - try { - // most tools have it implemented as a property - return (new Intl.Locale(locale) as any).calendars; - } catch { - try { - // but a few use methods, which is the preferred way - return (new Intl.Locale(locale) as any).getCalendars(); - } catch { - return undefined; - } - } -} - -function getMonthYearPattern (locale: string | undefined, date: Date): string { - let pattern = date.toLocaleDateString(locale, { year: "numeric", month: "long" }).toLowerCase(); - // pattern has month name as string or as number - const monthName = date.toLocaleString(locale, { month: "long" }).toLowerCase().trim(); - if (monthName.charAt(monthName.length - 1) == "\u6708") { - // Chineese-like patterns: - return "yyyy\u5e74M\u6708"; - } - pattern = pattern.replace(monthName, MONTH_CODE); - pattern = pattern.replace("999", YEAR_CODE); - // sometimes the number is localized and the above does not have an effect - const yearStr = date.toLocaleDateString(locale, { year: "numeric" }); - return pattern.replace(yearStr, YEAR_CODE); -} - -function getMonthDayPattern (locale: string | undefined, date: Date): string { - let pattern = date.toLocaleDateString(locale, { month: "long", day: "numeric" }).toLowerCase(); - // pattern has month name as string or as number - const monthName = date.toLocaleString(locale, { month: "long" }).toLowerCase().trim(); - if (monthName.charAt(monthName.length - 1) == "\u6708") { - // Chineese-like patterns: - return "M\u6708d\u65e5"; - } - const formatWithoutMonthName = new Intl.DateTimeFormat(locale, { day: "numeric" }); - const replacedMonthName = getGenitiveForName(date, pattern, monthName, formatWithoutMonthName); - pattern = pattern.replace(replacedMonthName, MONTH_CODE); - pattern = pattern.replace("22", DAY_CODE); - const dayStr = formatWithoutMonthName.format(date); - return pattern.replace(dayStr, DAY_CODE); -} - -function getShortDatePattern (locale: string | undefined): string { - if (locale?.substring(0, 2) == "fa") { - // persian calendar is shifted and it has no lapping dates with - // arabic and gregorian calendars, so that both day and month would be < 10 - return "yyyy/M/d"; - } - const year = 2014; - const month = 1; - const day = 2; - const date = new Date(year, month - 1, day); // arabic: 1/3/1435 - const longYearStr = "2014"; - const shortYearStr = "14"; - const longMonthStr = "01"; - const shortMonthStr = "1"; - const longDayStr = "02"; - const shortDayStr = "2"; - let pattern = date.toLocaleDateString(locale, { dateStyle: "short" }); - // each date part might be in localized numbers or standard arabic numbers - // toLocaleDateString returns not compatible data, - // e.g. { dateStyle: "short" } sometimes contains localized year number - // while { year: "numeric" } contains non-localized year number and vice versa - if (pattern.includes(shortYearStr)) { - pattern = pattern.replace(longYearStr, YEAR_CODE); - pattern = pattern.replace(shortYearStr, YEAR_CODE); - } else { - const yearStr = date.toLocaleDateString(locale, { year: "numeric" }); - const yearStrShort = yearStr.substring(yearStr.length - 2, yearStr.length); - pattern = pattern.replace(yearStr, YEAR_CODE); - if (yearStrShort) - pattern = pattern.replace(yearStrShort, YEAR_CODE); - } - - if (pattern.includes(shortMonthStr)) { - pattern = pattern.replace(longMonthStr, "MM"); - pattern = pattern.replace(shortMonthStr, "M"); - } else { - const monthStr = date.toLocaleDateString(locale, { month: "numeric" }); - const localizedMonthCode = monthStr.length == 1 ? "M" : "MM"; - pattern = pattern.replace(monthStr, localizedMonthCode); - } - - if (pattern.includes(shortDayStr)) { - pattern = pattern.replace(longDayStr, "dd"); - pattern = pattern.replace(shortDayStr, "d"); - } else { - const dayStr = date.toLocaleDateString(locale, { day: "numeric" }); - const localizedDayCode = dayStr.length == 1 ? "d" : "dd"; - pattern = pattern.replace(dayStr, localizedDayCode); - } - return pattern; -} - -function getLongDatePattern (locale: string | undefined, date: Date): string { - if (locale == "th-TH") { - // cannot be caught with regexes - return "ddddที่ d MMMM g yyyy"; - } - let pattern = new Intl.DateTimeFormat(locale, { weekday: "long", year: "numeric", month: "long", day: "numeric" }).format(date).toLowerCase(); - const monthName = date.toLocaleString(locale, { month: "long" }).trim().toLowerCase(); - - // pattern has month name as string or as number - const monthSuffix = monthName.charAt(monthName.length - 1); - if (monthSuffix == "\u6708" || monthSuffix == "\uc6d4") { - // Asian-like patterns: - const shortMonthName = date.toLocaleString(locale, { month: "short" }); - pattern = pattern.replace(shortMonthName, `M${monthSuffix}`); - } else { - const replacedMonthName = getGenitiveForName(date, pattern, monthName, new Intl.DateTimeFormat(locale, { weekday: "long", year: "numeric", day: "numeric" })); - pattern = pattern.replace(replacedMonthName, MONTH_CODE); - } - pattern = pattern.replace("999", YEAR_CODE); - // sometimes the number is localized and the above does not have an effect, - // so additionally, we need to do: - const yearStr = date.toLocaleDateString(locale, { year: "numeric" }); - pattern = pattern.replace(yearStr, YEAR_CODE); - const weekday = date.toLocaleDateString(locale, { weekday: "long" }).toLowerCase(); - const replacedWeekday = getGenitiveForName(date, pattern, weekday, new Intl.DateTimeFormat(locale, { year: "numeric", month: "long", day: "numeric" })); - pattern = pattern.replace(replacedWeekday, WEEKDAY_CODE); - pattern = pattern.replace("22", DAY_CODE); - const dayStr = date.toLocaleDateString(locale, { day: "numeric" }); // should we replace it for localized digits? - pattern = pattern.replace(dayStr, DAY_CODE); - return wrapSubstrings(pattern, locale); -} - -function getGenitiveForName (date: Date, pattern: string, name: string, formatWithoutName: Intl.DateTimeFormat) { - let genitiveName = name; - const nameStart = pattern.indexOf(name); - if (nameStart == -1 || - // genitive month name can include monthName and monthName can include spaces, e.g. "tháng 11":, so we cannot use pattern.includes() or pattern.split(" ").includes() - (nameStart != -1 && pattern.length > nameStart + name.length && pattern[nameStart + name.length] != " " && pattern[nameStart + name.length] != "," && pattern[nameStart + name.length] != "\u060c")) { - // needs to be in Genitive form to be useful - // e.g. - // pattern = '999 m. lapkričio 22 d., šeštadienis', - // patternWithoutName = '999 2, šeštadienis', - // name = 'lapkritis' - // genitiveName = 'lapkričio' - const patternWithoutName = formatWithoutName.format(date).toLowerCase(); - genitiveName = pattern.split(/,| /).filter(x => !patternWithoutName.split(/,| /).includes(x) && x[0] == name[0])[0]; - } - return genitiveName; -} - -function getDayNames (locale: string | undefined) : { long: string[], abbreviated: string[], shortest: string[] } { - const weekDay = new Date(2023, 5, 25); // Sunday - const dayNames = []; - const dayNamesAbb = []; - const dayNamesSS = []; - for (let i = 0; i < 7; i++) { - dayNames[i] = weekDay.toLocaleDateString(locale, { weekday: "long" }); - dayNamesAbb[i] = weekDay.toLocaleDateString(locale, { weekday: "short" }); - dayNamesSS[i] = weekDay.toLocaleDateString(locale, { weekday: "narrow" }); - weekDay.setDate(weekDay.getDate() + 1); - } - return { long: dayNames, abbreviated: dayNamesAbb, shortest: dayNamesSS }; -} - -function getMonthNames (locale: string | undefined) : { long: string[], abbreviated: string[], longGenitive: string[], abbreviatedGenitive: string[] } { - // some calendars have the first month on non-0 index in JS - // first month: Muharram ("ar") or Farwardin ("fa") or January - const localeLang = locale ? locale.split("-")[0] : ""; - const firstMonthShift = localeLang == "ar" ? 8 : localeLang == "fa" ? 3 : 0; - const date = new Date(2021, firstMonthShift, 1); - const months: string[] = []; - const monthsAbb: string[] = []; - const monthsGen: string[] = []; - const monthsAbbGen: string[] = []; - let isChineeseStyle, isShortFormBroken; - for (let i = firstMonthShift; i < 12 + firstMonthShift; i++) { - const monthCnt = i % 12; - date.setMonth(monthCnt); - - const monthNameLong = date.toLocaleDateString(locale, { month: "long" }); - const monthNameShort = date.toLocaleDateString(locale, { month: "short" }); - months[i - firstMonthShift] = monthNameLong; - monthsAbb[i - firstMonthShift] = monthNameShort; - // for Genitive forms: - isChineeseStyle = isChineeseStyle ?? monthNameLong.charAt(monthNameLong.length - 1) == "\u6708"; - if (isChineeseStyle) { - // for Chinese-like calendar's Genitive = Nominative - monthsGen[i - firstMonthShift] = monthNameLong; - monthsAbbGen[i - firstMonthShift] = monthNameShort; - continue; - } - const formatWithoutMonthName = new Intl.DateTimeFormat(locale, { day: "numeric" }); - const monthWithDayLong = date.toLocaleDateString(locale, { month: "long", day: "numeric" }); - monthsGen[i - firstMonthShift] = getGenitiveForName(date, monthWithDayLong, monthNameLong, formatWithoutMonthName); - isShortFormBroken = isShortFormBroken ?? /^\d+$/.test(monthNameShort); - if (isShortFormBroken) { - // for buggy locales e.g. lt-LT, short month contains only number instead of string - // we leave Genitive = Nominative - monthsAbbGen[i - firstMonthShift] = monthNameShort; - continue; - } - const monthWithDayShort = date.toLocaleDateString(locale, { month: "short", day: "numeric" }); - monthsAbbGen[i - firstMonthShift] = getGenitiveForName(date, monthWithDayShort, monthNameShort, formatWithoutMonthName); - } - return { long: months, abbreviated: monthsAbb, longGenitive: monthsGen, abbreviatedGenitive: monthsAbbGen }; -} - -// .NET expects that only the Japanese calendars have more than 1 era. -// So for other calendars, only return the latest era. -function getEraNames (date: Date, locale: string | undefined, calendarId: number) : { eraNames: string, abbreviatedEraNames: string} { - if (shouldBePopulatedByManagedCode(calendarId)) { - // managed code already handles these calendars, - // so empty strings will get overwritten in - // InitializeEraNames/InitializeAbbreviatedEraNames - return { - eraNames: "", - abbreviatedEraNames: "" - }; - } - const yearStr = date.toLocaleDateString(locale, { year: "numeric" }); - const dayStr = date.toLocaleDateString(locale, { day: "numeric" }); - const eraDate = date.toLocaleDateString(locale, { era: "short" }); - const shortEraDate = date.toLocaleDateString(locale, { era: "narrow" }); - - const eraDateParts = eraDate.includes(yearStr) ? - getEraDateParts(yearStr) : - getEraDateParts(date.getFullYear().toString()); - - return { - eraNames: getEraFromDateParts(eraDateParts.eraDateParts, eraDateParts.ignoredPart), - abbreviatedEraNames: getEraFromDateParts(eraDateParts.abbrEraDateParts, eraDateParts.ignoredPart) - }; - - function shouldBePopulatedByManagedCode (calendarId: number) { - return (calendarId > 1 && calendarId < 15) || calendarId == 22 || calendarId == 23; - } - - function getEraFromDateParts (dateParts: string[], ignoredPart: string) : string { - const regex = new RegExp(`^((?!${ignoredPart}|[0-9]).)*$`); - const filteredEra = dateParts.filter(part => regex.test(part)); - if (filteredEra.length == 0) - throw new Error(`Internal error, era for locale ${locale} was in non-standard format.`); - return filteredEra[0].trim(); - } - - function getEraDateParts (yearStr: string) { - if (eraDate.startsWith(yearStr) || eraDate.endsWith(yearStr)) { - return { - eraDateParts: eraDate.split(dayStr), - abbrEraDateParts: shortEraDate.split(dayStr), - ignoredPart: yearStr, - }; - } - return { - eraDateParts: eraDate.split(yearStr), - abbrEraDateParts: shortEraDate.split(yearStr), - ignoredPart: dayStr, - }; - } -} - -// wraps all substrings in the format in quotes, except for key words -// transform e.g. "dddd, d MMMM yyyy г." into "dddd, d MMMM yyyy 'г'." -function wrapSubstrings (str: string, locale: string | undefined) { - const words = str.split(/\s+/); - // locales that write date nearly without spaces should not have format parts quoted - "ja", "zh" - // "ko" format parts should not be quoted but processing it would overcomplicate the logic - if (words.length <= 2 || locale?.startsWith("ko")) { - return str; - } - - for (let i = 0; i < words.length; i++) { - if (!keyWords.includes(words[i].replace(",", "")) && - !keyWords.includes(words[i].replace(".", "")) && - !keyWords.includes(words[i].replace("\u060c", "")) && - !keyWords.includes(words[i].replace("\u05d1", ""))) { - if (words[i].endsWith(".,")) { - // if the "word" appears twice, then the occurence with punctuation is not a code but fixed part of the format - // see: "hu-HU" vs "lt-LT" format - const wordNoPuctuation = words[i].slice(0, -2); - if (words.filter(x => x == wordNoPuctuation).length == 1) - words[i] = `'${words[i].slice(0, -2)}'.,`; - } else if (words[i].endsWith(".")) { - words[i] = `'${words[i].slice(0, -1)}'.`; - } else if (words[i].endsWith(",")) { - words[i] = `'${words[i].slice(0, -1)}',`; - } else { - words[i] = `'${words[i]}'`; - } - } - } - return words.join(" "); -} diff --git a/src/mono/browser/runtime/hybrid-globalization/change-case.ts b/src/mono/browser/runtime/hybrid-globalization/change-case.ts deleted file mode 100644 index 0024b5b45d5d1..0000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/change-case.ts +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { VoidPtrNull } from "../types/internal"; -import { runtimeHelpers } from "./module-exports"; -import { VoidPtr } from "../types/emscripten"; -import { isSurrogate } from "./helpers"; - -export function mono_wasm_change_case (culture: number, cultureLength: number, src: number, srcLength: number, dst: number, dstLength: number, toUpper: number): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - if (!cultureName) - throw new Error("Cannot change case, the culture name is null."); - const input = runtimeHelpers.utf16ToStringLoop(src, src + 2 * srcLength); - const result = toUpper ? input.toLocaleUpperCase(cultureName) : input.toLocaleLowerCase(cultureName); - - if (result.length <= input.length) { - runtimeHelpers.stringToUTF16(dst, dst + 2 * dstLength, result); - return VoidPtrNull; - } - // workaround to maintain the ICU-like behavior - const heapI16 = runtimeHelpers.localHeapViewU16(); - let jump = 1; - if (toUpper) { - for (let i = 0; i < input.length; i += jump) { - // surrogate parts have to enter ToUpper/ToLower together to give correct output - if (isSurrogate(input, i)) { - jump = 2; - const surrogate = input.substring(i, i + 2); - const upperSurrogate = surrogate.toLocaleUpperCase(cultureName); - const appendedSurrogate = upperSurrogate.length > 2 ? surrogate : upperSurrogate; - appendSurrogateToMemory(heapI16, dst, appendedSurrogate, i); - - } else { - jump = 1; - const upperChar = input[i].toLocaleUpperCase(cultureName); - const appendedChar = upperChar.length > 1 ? input[i] : upperChar; - runtimeHelpers.setU16_local(heapI16, dst + i * 2, appendedChar.charCodeAt(0)); - } - } - } else { - for (let i = 0; i < input.length; i += jump) { - // surrogate parts have to enter ToUpper/ToLower together to give correct output - if (isSurrogate(input, i)) { - jump = 2; - const surrogate = input.substring(i, i + 2); - const upperSurrogate = surrogate.toLocaleLowerCase(cultureName); - const appendedSurrogate = upperSurrogate.length > 2 ? surrogate : upperSurrogate; - appendSurrogateToMemory(heapI16, dst, appendedSurrogate, i); - } else { - jump = 1; - const lowerChar = input[i].toLocaleLowerCase(cultureName); - const appendedChar = lowerChar.length > 1 ? input[i] : lowerChar; - runtimeHelpers.setU16_local(heapI16, dst + i * 2, appendedChar.charCodeAt(0)); - } - } - } - return VoidPtrNull; - } catch (ex: any) { - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -function appendSurrogateToMemory (heapI16: Uint16Array, dst: number, surrogate: string, idx: number) { - runtimeHelpers.setU16_local(heapI16, dst + idx * 2, surrogate.charCodeAt(0)); - runtimeHelpers.setU16_local(heapI16, dst + (idx + 1) * 2, surrogate.charCodeAt(1)); -} diff --git a/src/mono/browser/runtime/hybrid-globalization/collations.ts b/src/mono/browser/runtime/hybrid-globalization/collations.ts deleted file mode 100644 index 026cd942ea99e..0000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/collations.ts +++ /dev/null @@ -1,268 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { VoidPtrNull } from "../types/internal"; -import { runtimeHelpers } from "./module-exports"; -import { Int32Ptr, VoidPtr } from "../types/emscripten"; -import { GraphemeSegmenter } from "./grapheme-segmenter"; - -const COMPARISON_ERROR = -2; -const INDEXING_ERROR = -1; -let graphemeSegmenterCached: GraphemeSegmenter | null; - -export function mono_wasm_compare_string (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const string1 = runtimeHelpers.utf16ToString(str1, (str1 + 2 * str1Length)); - const string2 = runtimeHelpers.utf16ToString(str2, (str2 + 2 * str2Length)); - const compareOptions = (options & 0x3f); - const locale = cultureName ? cultureName : undefined; - const result = compareStrings(string1, string2, locale, compareOptions); - runtimeHelpers.setI32(resultPtr, result); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(resultPtr, COMPARISON_ERROR); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -export function mono_wasm_starts_with (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const prefix = decodeToCleanString(str2, str2Length); - // no need to look for an empty string - if (prefix.length == 0) { - runtimeHelpers.setI32(resultPtr, 1); // true - return VoidPtrNull; - } - - const source = decodeToCleanString(str1, str1Length); - if (source.length < prefix.length) { - runtimeHelpers.setI32(resultPtr, 0); // false - return VoidPtrNull; - } - const sourceOfPrefixLength = source.slice(0, prefix.length); - - const casePicker = (options & 0x3f); - const locale = cultureName ? cultureName : undefined; - const cmpResult = compareStrings(sourceOfPrefixLength, prefix, locale, casePicker); - const result = cmpResult === 0 ? 1 : 0; // equals ? true : false - runtimeHelpers.setI32(resultPtr, result); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(resultPtr, INDEXING_ERROR); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -export function mono_wasm_ends_with (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const suffix = decodeToCleanString(str2, str2Length); - if (suffix.length == 0) { - runtimeHelpers.setI32(resultPtr, 1); // true - return VoidPtrNull; - } - - const source = decodeToCleanString(str1, str1Length); - const diff = source.length - suffix.length; - if (diff < 0) { - runtimeHelpers.setI32(resultPtr, 0); // false - return VoidPtrNull; - } - const sourceOfSuffixLength = source.slice(diff, source.length); - - const casePicker = (options & 0x3f); - const locale = cultureName ? cultureName : undefined; - const cmpResult = compareStrings(sourceOfSuffixLength, suffix, locale, casePicker); - const result = cmpResult === 0 ? 1 : 0; // equals ? true : false - runtimeHelpers.setI32(resultPtr, result); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(resultPtr, INDEXING_ERROR); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -export function mono_wasm_index_of (culture: number, cultureLength: number, needlePtr: number, needleLength: number, srcPtr: number, srcLength: number, options: number, fromBeginning: number, resultPtr: Int32Ptr): VoidPtr { - try { - const needle = decodeToCleanStringForIndexing(needlePtr, needleLength); - // no need to look for an empty string - if (cleanString(needle).length == 0) { - runtimeHelpers.setI32(resultPtr, fromBeginning ? 0 : srcLength); - return VoidPtrNull; - } - - const source = decodeToCleanStringForIndexing(srcPtr, srcLength); - // no need to look in an empty string - if (cleanString(source).length == 0) { - runtimeHelpers.setI32(resultPtr, fromBeginning ? 0 : srcLength); - return VoidPtrNull; - } - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const locale = cultureName ? cultureName : undefined; - const casePicker = (options & 0x3f); - let result = -1; - - const graphemeSegmenter = graphemeSegmenterCached || (graphemeSegmenterCached = new GraphemeSegmenter()); - const needleSegments = []; - let needleIdx = 0; - - // Grapheme segmentation of needle string - while (needleIdx < needle.length) { - const needleGrapheme = graphemeSegmenter.nextGrapheme(needle, needleIdx); - needleSegments.push(needleGrapheme); - needleIdx += needleGrapheme.length; - } - - let srcIdx = 0; - while (srcIdx < source.length) { - const srcGrapheme = graphemeSegmenter.nextGrapheme(source, srcIdx); - srcIdx += srcGrapheme.length; - - if (!checkMatchFound(srcGrapheme, needleSegments[0], locale, casePicker)) { - continue; - } - - let j; - let srcNextIdx = srcIdx; - for (j = 1; j < needleSegments.length; j++) { - const srcGrapheme = graphemeSegmenter.nextGrapheme(source, srcNextIdx); - - if (!checkMatchFound(srcGrapheme, needleSegments[j], locale, casePicker)) { - break; - } - srcNextIdx += srcGrapheme.length; - } - if (j === needleSegments.length) { - result = srcIdx - srcGrapheme.length; - if (fromBeginning) - break; - } - } - runtimeHelpers.setI32(resultPtr, result); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(resultPtr, INDEXING_ERROR); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } - - function checkMatchFound (str1: string, str2: string, locale: string | undefined, casePicker: number): boolean { - return compareStrings(str1, str2, locale, casePicker) === 0; - } -} - -function compareStrings (string1: string, string2: string, locale: string | undefined, compareOptions: number): number { - let options: Intl.CollatorOptions | undefined = undefined; - - const numericOrderingFlag = 0x20; - if (compareOptions & numericOrderingFlag) { - options = { numeric: true }; - } - - switch (compareOptions & (~numericOrderingFlag)) { - case 0: - // 0: None - default algorithm for the platform OR - // StringSort - for ICU it gives the same result as None, see: https://github.com/dotnet/dotnet-api-docs/issues - // does not work for "ja" - if (locale && locale.split("-")[0] === "ja") - return COMPARISON_ERROR; - return string1.localeCompare(string2, locale, options); // a ≠ b, a ≠ á, a ≠ A - case 8: - // 8: IgnoreKanaType works only for "ja" - if (locale && locale.split("-")[0] !== "ja") - return COMPARISON_ERROR; - return string1.localeCompare(string2, locale, options); // a ≠ b, a ≠ á, a ≠ A - case 1: - // 1: IgnoreCase - string1 = string1.toLocaleLowerCase(locale); - string2 = string2.toLocaleLowerCase(locale); - return string1.localeCompare(string2, locale, options); // a ≠ b, a ≠ á, a ≠ A - case 4: - case 12: - // 4: IgnoreSymbols - // 12: IgnoreKanaType | IgnoreSymbols - return string1.localeCompare(string2, locale, { ignorePunctuation: true, ...options }); // by default ignorePunctuation: false - case 5: - // 5: IgnoreSymbols | IgnoreCase - string1 = string1.toLocaleLowerCase(locale); - string2 = string2.toLocaleLowerCase(locale); - return string1.localeCompare(string2, locale, { ignorePunctuation: true, ...options }); // a ≠ b, a ≠ á, a ≠ A - case 9: - // 9: IgnoreKanaType | IgnoreCase - return string1.localeCompare(string2, locale, { sensitivity: "accent", ...options }); // a ≠ b, a ≠ á, a = A - case 10: - // 10: IgnoreKanaType | IgnoreNonSpace - return string1.localeCompare(string2, locale, { sensitivity: "case", ...options }); // a ≠ b, a = á, a ≠ A - case 11: - // 11: IgnoreKanaType | IgnoreNonSpace | IgnoreCase - return string1.localeCompare(string2, locale, { sensitivity: "base", ...options }); // a ≠ b, a = á, a = A - case 13: - // 13: IgnoreKanaType | IgnoreCase | IgnoreSymbols - return string1.localeCompare(string2, locale, { sensitivity: "accent", ignorePunctuation: true, ...options }); // a ≠ b, a ≠ á, a = A - case 14: - // 14: IgnoreKanaType | IgnoreSymbols | IgnoreNonSpace - return string1.localeCompare(string2, locale, { sensitivity: "case", ignorePunctuation: true, ...options });// a ≠ b, a = á, a ≠ A - case 15: - // 15: IgnoreKanaType | IgnoreSymbols | IgnoreNonSpace | IgnoreCase - return string1.localeCompare(string2, locale, { sensitivity: "base", ignorePunctuation: true, ...options }); // a ≠ b, a = á, a = A - case 2: - case 3: - case 6: - case 7: - case 16: - case 17: - case 18: - case 19: - case 20: - case 21: - case 22: - case 23: - case 24: - case 25: - case 26: - case 27: - case 28: - case 29: - case 30: - case 31: - default: - // 2: IgnoreNonSpace - // 3: IgnoreNonSpace | IgnoreCase - // 6: IgnoreSymbols | IgnoreNonSpace - // 7: IgnoreSymbols | IgnoreNonSpace | IgnoreCase - // 16: IgnoreWidth - // 17: IgnoreWidth | IgnoreCase - // 18: IgnoreWidth | IgnoreNonSpace - // 19: IgnoreWidth | IgnoreNonSpace | IgnoreCase - // 20: IgnoreWidth | IgnoreSymbols - // 21: IgnoreWidth | IgnoreSymbols | IgnoreCase - // 22: IgnoreWidth | IgnoreSymbols | IgnoreNonSpace - // 23: IgnoreWidth | IgnoreSymbols | IgnoreNonSpace | IgnoreCase - // 24: IgnoreKanaType | IgnoreWidth - // 25: IgnoreKanaType | IgnoreWidth | IgnoreCase - // 26: IgnoreKanaType | IgnoreWidth | IgnoreNonSpace - // 27: IgnoreKanaType | IgnoreWidth | IgnoreNonSpace | IgnoreCase - // 28: IgnoreKanaType | IgnoreWidth | IgnoreSymbols - // 29: IgnoreKanaType | IgnoreWidth | IgnoreSymbols | IgnoreCase - // 30: IgnoreKanaType | IgnoreWidth | IgnoreSymbols | IgnoreNonSpace - // 31: IgnoreKanaType | IgnoreWidth | IgnoreSymbols | IgnoreNonSpace | IgnoreCase - throw new Error(`Invalid comparison option. Option=${compareOptions}`); - } -} - -function decodeToCleanString (strPtr: number, strLen: number) { - const str = runtimeHelpers.utf16ToString(strPtr, (strPtr + 2 * strLen)); - return cleanString(str); -} - -function cleanString (str: string) { - const nStr = str.normalize(); - return nStr.replace(/[\u200B-\u200D\uFEFF\0\u00AD]/g, ""); -} - -// in ICU indexing only SoftHyphen is weightless -function decodeToCleanStringForIndexing (strPtr: number, strLen: number) { - const str = runtimeHelpers.utf16ToString(strPtr, (strPtr + 2 * strLen)); - return str.replace(/[\u00AD]/g, ""); -} diff --git a/src/mono/browser/runtime/hybrid-globalization/culture-info.ts b/src/mono/browser/runtime/hybrid-globalization/culture-info.ts deleted file mode 100644 index b62b50854408d..0000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/culture-info.ts +++ /dev/null @@ -1,139 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { VoidPtrNull } from "../types/internal"; -import { runtimeHelpers } from "./module-exports"; -import { Int32Ptr, VoidPtr } from "../types/emscripten"; -import { OUTER_SEPARATOR, normalizeLocale } from "./helpers"; - -const NO_PREFIX_24H = "H"; -const PREFIX_24H = "HH"; -const NO_PREFIX_12H = "h"; -const PREFIX_12H = "hh"; -const SECONDS_CODE = "ss"; -const MINUTES_CODE = "mm"; -const DESIGNATOR_CODE = "tt"; -// Note: wrapSubstrings -// The character "h" can be ambiguous as it might represent an hour code hour code and a fixed (quoted) part of the format. -// Special Case for "fr-CA": Always recognize "HH" as a keyword and do not quote it, to avoid formatting issues. -const keyWords = [SECONDS_CODE, MINUTES_CODE, DESIGNATOR_CODE, PREFIX_24H]; - -export function mono_wasm_get_culture_info (culture: number, cultureLength: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const cultureInfo = { - AmDesignator: "", - PmDesignator: "", - LongTimePattern: "", - ShortTimePattern: "" - }; - const canonicalLocale = normalizeLocale(cultureName); - const designators = getAmPmDesignators(canonicalLocale); - cultureInfo.AmDesignator = designators.am; - cultureInfo.PmDesignator = designators.pm; - cultureInfo.LongTimePattern = getLongTimePattern(canonicalLocale, designators); - cultureInfo.ShortTimePattern = getShortTimePattern(cultureInfo.LongTimePattern); - const result = Object.values(cultureInfo).join(OUTER_SEPARATOR); - if (result.length > dstMaxLength) { - throw new Error(`Culture info exceeds length of ${dstMaxLength}.`); - } - runtimeHelpers.stringToUTF16(dst, dst + 2 * result.length, result); - runtimeHelpers.setI32(dstLength, result.length); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(dstLength, -1); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -function getAmPmDesignators (locale: any) { - const pmTime = new Date("August 19, 1975 12:15:33"); // do not change, some PM hours result in hour digits change, e.g. 13 -> 01 or 1 - const amTime = new Date("August 19, 1975 11:15:33"); // do not change, some AM hours result in hour digits change, e.g. 9 -> 09 - const pmDesignator = getDesignator(pmTime, locale); - const amDesignator = getDesignator(amTime, locale); - return { - am: amDesignator, - pm: pmDesignator - }; -} - -function getDesignator (time: Date, locale: string) { - let withDesignator = time.toLocaleTimeString(locale, { hourCycle: "h12" }); - const localizedZero = (0).toLocaleString(locale); - if (withDesignator.includes(localizedZero)) { - // in v8>=11.8 "12" changes to "0" for ja-JP - const localizedTwelve = (12).toLocaleString(locale); - withDesignator = withDesignator.replace(localizedZero, localizedTwelve); - } - const withoutDesignator = time.toLocaleTimeString(locale, { hourCycle: "h24" }); - const designator = withDesignator.replace(withoutDesignator, "").trim(); - if (new RegExp("[0-9]$").test(designator)) { - const designatorParts = withDesignator.split(" ").filter(part => new RegExp("^((?![0-9]).)*$").test(part)); - if (!designatorParts || designatorParts.length == 0) - return ""; - return designatorParts.join(" "); - } - return designator; -} - -function getLongTimePattern (locale: string | undefined, designators: any): string { - const hourIn24Format = 18; // later hours than 18 have night designators in some locales (instead of AM designator) - const hourIn12Format = 6; - const localizedHour24 = (hourIn24Format).toLocaleString(locale); // not all locales use arabic numbers - const localizedHour12 = (hourIn12Format).toLocaleString(locale); - const pmTime = new Date(`August 19, 1975 ${hourIn24Format}:15:30`); // in the comments, en-US locale is used: - const shortTime = new Intl.DateTimeFormat(locale, { timeStyle: "medium" }); - const shortPmStyle = shortTime.format(pmTime); // 12:15:30 PM - const minutes = pmTime.toLocaleTimeString(locale, { minute: "numeric" }); // 15 - const seconds = pmTime.toLocaleTimeString(locale, { second: "numeric" }); // 30 - let pattern = shortPmStyle.replace(designators.pm, DESIGNATOR_CODE).replace(minutes, MINUTES_CODE).replace(seconds, SECONDS_CODE); // 12:mm:ss tt - - const isISOStyle = pattern.includes(localizedHour24); // 24h or 12h pattern? - const localized0 = (0).toLocaleString(locale); - const hour12WithPrefix = `${localized0}${localizedHour12}`; // 06 - const amTime = new Date(`August 19, 1975 ${hourIn12Format}:15:30`); - const h12Style = shortTime.format(amTime); - let hourPattern; - if (isISOStyle) { // 24h - const hasPrefix = h12Style.includes(hour12WithPrefix); - hourPattern = hasPrefix ? PREFIX_24H : NO_PREFIX_24H; - pattern = pattern.replace(localizedHour24, hourPattern); - } else { // 12h - const hasPrefix = h12Style.includes(hour12WithPrefix); - hourPattern = hasPrefix ? PREFIX_12H : NO_PREFIX_12H; - pattern = pattern.replace(hasPrefix ? hour12WithPrefix : localizedHour12, hourPattern); - } - return wrapSubstrings(pattern); -} - -function getShortTimePattern (pattern: string): string { - // remove seconds: - // short dotnet pattern does not contain seconds while JS's pattern always contains them - const secondsIdx = pattern.indexOf(SECONDS_CODE); - if (secondsIdx > 0) { - const secondsWithSeparator = `${pattern[secondsIdx - 1]}${SECONDS_CODE}`; - // en-US: 12:mm:ss tt -> 12:mm tt; - // fr-CA: 12 h mm min ss s -> 12 h mm min s - const shortPatternNoSecondsDigits = pattern.replace(secondsWithSeparator, ""); - if (shortPatternNoSecondsDigits.length > secondsIdx && shortPatternNoSecondsDigits[shortPatternNoSecondsDigits.length - 1] != "t") { - pattern = pattern.split(secondsWithSeparator)[0]; - } else { - pattern = shortPatternNoSecondsDigits; - } - } - return pattern; -} - -// wraps all substrings in the format in quotes, except for key words -// transform e.g. "HH h mm min ss s" into "HH 'h' mm 'min' ss 's'" -function wrapSubstrings (str: string) { - const words = str.split(/\s+/); - - for (let i = 0; i < words.length; i++) { - if (!words[i].includes(":") && !words[i].includes(".") && !keyWords.includes(words[i])) { - words[i] = `'${words[i]}'`; - } - } - - return words.join(" "); -} diff --git a/src/mono/browser/runtime/hybrid-globalization/grapheme-segmenter.ts b/src/mono/browser/runtime/hybrid-globalization/grapheme-segmenter.ts deleted file mode 100644 index 251304dcc902b..0000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/grapheme-segmenter.ts +++ /dev/null @@ -1,142 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/** - * This file is partially using code from FormatJS Intl.Segmenter implementation, reference: - * https://github.com/formatjs/formatjs/blob/58d6a7b398d776ca3d2726d72ae1573b65cc3bef/packages/intl-segmenter/src/segmenter.ts - * https://github.com/formatjs/formatjs/blob/58d6a7b398d776ca3d2726d72ae1573b65cc3bef/packages/intl-segmenter/src/segmentation-utils.ts - */ - -import { isSurrogate } from "./helpers"; - -type SegmentationRule = { - breaks: boolean - before?: RegExp - after?: RegExp -} - -type SegmentationRuleRaw = { - breaks: boolean - before?: string - after?: string -} - -type SegmentationTypeRaw = { - variables: Record - rules: Record -} - -let segmentationRules: Record; - -function replaceVariables (variables: Record, input: string): string { - const findVarRegex = /\$[A-Za-z0-9_]+/gm; - return input.replaceAll(findVarRegex, match => { - if (!(match in variables)) { - throw new Error(`No such variable ${match}`); - } - return variables[match]; - }); -} - -function generateRegexRule (rule: string, variables: Record, after: boolean): RegExp { - return new RegExp(`${after ? "^" : ""}${replaceVariables(variables, rule)}${after ? "" : "$"}`); -} - -function isSegmentationTypeRaw (obj: any): obj is SegmentationTypeRaw { - return obj.variables != null && obj.rules != null; -} - -export function setSegmentationRulesFromJson (json: string) { - if (!isSegmentationTypeRaw(json)) - throw new Error("Provided grapheme segmentation rules are not valid"); - segmentationRules = GraphemeSegmenter.prepareSegmentationRules(json); -} - -export class GraphemeSegmenter { - private readonly rules: Record; - private readonly ruleSortedKeys: string[]; - - public constructor () { - this.rules = segmentationRules; - this.ruleSortedKeys = Object.keys(this.rules).sort((a, b) => Number(a) - Number(b)); - } - - /** - * Returns the next grapheme in the given string starting from the specified index. - * @param str - The input string. - * @param startIndex - The starting index. - * @returns The next grapheme. - */ - public nextGrapheme (str: string, startIndex: number): string { - const breakIdx = this.nextGraphemeBreak(str, startIndex); - return str.substring(startIndex, breakIdx); - } - - /** - * Finds the index of the next grapheme break in a given string starting from a specified index. - * - * @param str - The input string. - * @param startIndex - The index to start searching from. - * @returns The index of the next grapheme break. - */ - public nextGraphemeBreak (str: string, startIndex: number): number { - if (startIndex < 0) - return 0; - - if (startIndex >= str.length - 1) - return str.length; - - let prev = String.fromCodePoint(str.codePointAt(startIndex)!); - for (let i = startIndex + 1; i < str.length; i++) { - // Don't break surrogate pairs - if (isSurrogate(str, i)) { - continue; - } - - const curr = String.fromCodePoint(str.codePointAt(i)!); - if (this.isGraphemeBreak(prev, curr)) - return i; - - prev = curr; - } - - return str.length; - } - - private isGraphemeBreak (previous: string, current: string): boolean { - for (const key of this.ruleSortedKeys) { - const { before, after, breaks } = this.rules[key]; - // match before and after rules - if (before && !before.test(previous)) { - continue; - } - if (after && !after.test(current)) { - continue; - } - - return breaks; - } - - // GB999: Any ÷ Any - return true; - } - - public static prepareSegmentationRules (segmentationRules: SegmentationTypeRaw): Record { - const preparedRules: Record = {}; - - for (const key of Object.keys(segmentationRules.rules)) { - const ruleValue = segmentationRules.rules[key]; - const preparedRule: SegmentationRule = { breaks: ruleValue.breaks, }; - - if ("before" in ruleValue && ruleValue.before) { - preparedRule.before = generateRegexRule(ruleValue.before, segmentationRules.variables, false); - } - if ("after" in ruleValue && ruleValue.after) { - preparedRule.after = generateRegexRule(ruleValue.after, segmentationRules.variables, true); - } - - preparedRules[key] = preparedRule; - } - return preparedRules; - } -} diff --git a/src/mono/browser/runtime/hybrid-globalization/helpers.ts b/src/mono/browser/runtime/hybrid-globalization/helpers.ts deleted file mode 100644 index 5bf28026404a9..0000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/helpers.ts +++ /dev/null @@ -1,35 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -const SURROGATE_HIGHER_START = "\uD800"; -const SURROGATE_HIGHER_END = "\uDBFF"; -const SURROGATE_LOWER_START = "\uDC00"; -const SURROGATE_LOWER_END = "\uDFFF"; - -export const OUTER_SEPARATOR = "##"; -export const INNER_SEPARATOR = "||"; - -export function normalizeLocale (locale: string | null) { - if (!locale) - return undefined; - try { - locale = locale.toLocaleLowerCase(); - if (locale.includes("zh")) { - // browser does not recognize "zh-chs" and "zh-cht" as equivalents of "zh-HANS" "zh-HANT", we are helping, otherwise - // it would throw on getCanonicalLocales with "RangeError: Incorrect locale information provided" - locale = locale.replace("chs", "HANS").replace("cht", "HANT"); - } - const canonicalLocales = (Intl as any).getCanonicalLocales(locale.replace("_", "-")); - return canonicalLocales.length > 0 ? canonicalLocales[0] : undefined; - } catch { - return undefined; - } -} - -export function isSurrogate (str: string, startIdx: number): boolean { - return SURROGATE_HIGHER_START <= str[startIdx] && - str[startIdx] <= SURROGATE_HIGHER_END && - startIdx + 1 < str.length && - SURROGATE_LOWER_START <= str[startIdx + 1] && - str[startIdx + 1] <= SURROGATE_LOWER_END; -} diff --git a/src/mono/browser/runtime/hybrid-globalization/locales.ts b/src/mono/browser/runtime/hybrid-globalization/locales.ts deleted file mode 100644 index 0dc4c8bcc67fc..0000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/locales.ts +++ /dev/null @@ -1,89 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { VoidPtrNull } from "../types/internal"; -import { runtimeHelpers } from "./module-exports"; -import { Int32Ptr, VoidPtr } from "../types/emscripten"; -import { normalizeLocale } from "./helpers"; - -export function mono_wasm_get_first_day_of_week (culture: number, cultureLength: number, resultPtr: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const canonicalLocale = normalizeLocale(cultureName); - const result = getFirstDayOfWeek(canonicalLocale); - runtimeHelpers.setI32(resultPtr, result); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(resultPtr, -1); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -export function mono_wasm_get_first_week_of_year (culture: number, cultureLength: number, resultPtr: Int32Ptr): VoidPtr { - try { - const cultureName = runtimeHelpers.utf16ToString(culture, (culture + 2 * cultureLength)); - const canonicalLocale = normalizeLocale(cultureName); - const result = getFirstWeekOfYear(canonicalLocale); - runtimeHelpers.setI32(resultPtr, result); - return VoidPtrNull; - } catch (ex: any) { - runtimeHelpers.setI32(resultPtr, -1); - return runtimeHelpers.stringToUTF16Ptr(ex.toString()); - } -} - -function getFirstDayOfWeek (locale: string) { - const weekInfo = getWeekInfo(locale); - if (weekInfo) { - // JS's Sunday == 7 while dotnet's Sunday == 0 - return weekInfo.firstDay == 7 ? 0 : weekInfo.firstDay; - } - // Firefox does not support it rn but we can make a temporary workaround for it, - // that should be removed when it starts being supported: - const saturdayLocales = ["en-AE", "en-SD", "fa-IR"]; - if (saturdayLocales.includes(locale)) { - return 6; - } - const sundayLanguages = ["th", "pt", "mr", "ml", "ko", "kn", "ja", "id", "hi", "he", "gu", "fil", "bn", "am", "ar", "te"]; - const sundayLocales = ["ta-SG", "ta-IN", "sw-KE", "ms-SG", "fr-CA", "es-MX", "en-US", "en-ZW", "en-ZA", "en-WS", "en-VI", "en-UM", "en-TT", "en-SG", "en-PR", "en-PK", "en-PH", "en-MT", "en-MO", "en-MH", "en-KE", "en-JM", "en-IN", "en-IL", "en-HK", "en-GU", "en-DM", "en-CA", "en-BZ", "en-BW", "en-BS", "en-AS", "en-AG", "zh-Hans-HK", "zh-SG", "zh-HK", "zh-TW"]; // "en-AU" is Monday in chrome, so firefox should be in line - const localeLang = locale.split("-")[0]; - if (sundayLanguages.includes(localeLang) || sundayLocales.includes(locale)) { - return 0; - } - return 1; -} - -function getFirstWeekOfYear (locale: string) { - const weekInfo = getWeekInfo(locale); - if (weekInfo) { - // enum CalendarWeekRule - // FirstDay = 0, // when minimalDays < 4 - // FirstFullWeek = 1, // when miminalDays == 7 - // FirstFourDayWeek = 2 // when miminalDays >= 4 - return weekInfo.minimalDays == 7 ? 1 : - weekInfo.minimalDays < 4 ? 0 : 2; - } - // Firefox does not support it rn but we can make a temporary workaround for it, - // that should be removed when it starts being supported: - const firstFourDayWeekLocales = ["pt-PT", "fr-CH", "fr-FR", "fr-BE", "es-ES", "en-SE", "en-NL", "en-JE", "en-IM", "en-IE", "en-GI", "en-GG", "en-GB", "en-FJ", "en-FI", "en-DK", "en-DE", "en-CH", "en-BE", "en-AT", "el-GR", "nl-BE", "nl-NL"]; - const firstFourDayWeekLanguages = ["sv", "sk", "ru", "pl", "no", "nb", "lt", "it", "hu", "fi", "et", "de", "da", "cs", "ca", "bg"]; - const localeLang = locale.split("-")[0]; - if (firstFourDayWeekLocales.includes(locale) || firstFourDayWeekLanguages.includes(localeLang)) { - return 2; - } - return 0; -} - -function getWeekInfo (locale: string) { - try { - // most tools have it implemented as property - return (new Intl.Locale(locale) as any).weekInfo; - } catch { - try { - // but a few use methods, which is the preferred way - return (new Intl.Locale(locale) as any).getWeekInfo(); - } catch { - return undefined; - } - } -} diff --git a/src/mono/browser/runtime/hybrid-globalization/module-exports.ts b/src/mono/browser/runtime/hybrid-globalization/module-exports.ts deleted file mode 100644 index f17bf90d4f245..0000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/module-exports.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { GlobalizationHelpers, RuntimeHelpers } from "../types/internal"; -import { mono_wasm_get_calendar_info } from "./calendar"; -import { mono_wasm_change_case } from "./change-case"; -import { mono_wasm_compare_string, mono_wasm_starts_with, mono_wasm_ends_with, mono_wasm_index_of } from "./collations"; -import { mono_wasm_get_culture_info } from "./culture-info"; -import { setSegmentationRulesFromJson } from "./grapheme-segmenter"; -import { mono_wasm_get_first_day_of_week, mono_wasm_get_first_week_of_year } from "./locales"; - -export let globalizationHelpers: GlobalizationHelpers; -export let runtimeHelpers: RuntimeHelpers; - -export function initHybrid (gh: GlobalizationHelpers, rh: RuntimeHelpers) { - gh.mono_wasm_change_case = mono_wasm_change_case; - gh.mono_wasm_compare_string = mono_wasm_compare_string; - gh.mono_wasm_starts_with = mono_wasm_starts_with; - gh.mono_wasm_ends_with = mono_wasm_ends_with; - gh.mono_wasm_index_of = mono_wasm_index_of; - gh.mono_wasm_get_calendar_info = mono_wasm_get_calendar_info; - gh.mono_wasm_get_culture_info = mono_wasm_get_culture_info; - gh.mono_wasm_get_first_day_of_week = mono_wasm_get_first_day_of_week; - gh.mono_wasm_get_first_week_of_year = mono_wasm_get_first_week_of_year; - gh.setSegmentationRulesFromJson = setSegmentationRulesFromJson; - globalizationHelpers = gh; - runtimeHelpers = rh; -} - diff --git a/src/mono/browser/runtime/hybrid-globalization/segmentation-rules.json b/src/mono/browser/runtime/hybrid-globalization/segmentation-rules.json deleted file mode 100644 index f99c632f84317..0000000000000 --- a/src/mono/browser/runtime/hybrid-globalization/segmentation-rules.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "rules": { - "3": { - "after": "$LF", - "before": "$CR", - "breaks": false - }, - "4": { - "before": "($Control|$CR|$LF)", - "breaks": true - }, - "5": { - "after": "($Control|$CR|$LF)", - "breaks": true - }, - "6": { - "after": "($L|$V|$LV|$LVT)", - "before": "$L", - "breaks": false - }, - "7": { - "after": "($V|$T)", - "before": "($LV|$V)", - "breaks": false - }, - "8": { - "after": "$T", - "before": "($LVT|$T)", - "breaks": false - }, - "9": { - "after": "($Extend|$ZWJ)", - "breaks": false - }, - "11": { - "after": "$ExtPict", - "before": "$ExtPict$Extend*$ZWJ", - "breaks": false - }, - "12": { - "after": "$RI", - "before": "^($RI$RI)*$RI", - "breaks": false - }, - "13": { - "after": "$RI", - "before": "[^\\uDDE6-\\uDDFF]($RI$RI)*$RI", - "breaks": false - }, - "9.1": { - "after": "$SpacingMark", - "breaks": false - }, - "9.2": { - "before": "$Prepend", - "breaks": false - }, - "9.3": { - "after": "$LinkingConsonant", - "before": "$LinkingConsonant$ExtCccZwj*$Virama$ExtCccZwj*", - "breaks": false - } - }, - "variables": { - "$CR": "\\r", - "$Control": "(?:[\\0-\\t\\x0B\\f\\x0E-\\x1F\\x7F-\\x9F\\xAD\\u061C\\u180E\\u200B\\u200E\\u200F\\u2028-\\u202E\\u2060-\\u206F\\uFEFF\\uFFF0-\\uFFFB]|\\uD80D[\\uDC30-\\uDC3F]|\\uD82F[\\uDCA0-\\uDCA3]|\\uD834[\\uDD73-\\uDD7A]|\\uDB40[\\uDC00-\\uDC1F\\uDC80-\\uDCFF\\uDDF0-\\uDFFF]|[\\uDB41-\\uDB43][\\uDC00-\\uDFFF])", - "$ExtCccZwj": "(?:[\\u0300-\\u034E\\u0350-\\u036F\\u0483-\\u0487\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065F\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07EB-\\u07F3\\u07FD\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0859-\\u085B\\u0898-\\u089F\\u08CA-\\u08E1\\u08E3-\\u08FF\\u093C\\u094D\\u0951-\\u0954\\u09BC\\u09CD\\u09FE\\u0A3C\\u0A4D\\u0ABC\\u0ACD\\u0B3C\\u0B4D\\u0BCD\\u0C3C\\u0C4D\\u0C55\\u0C56\\u0CBC\\u0CCD\\u0D3B\\u0D3C\\u0D4D\\u0DCA\\u0E38-\\u0E3A\\u0E48-\\u0E4B\\u0EB8-\\u0EBA\\u0EC8-\\u0ECB\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71\\u0F72\\u0F74\\u0F7A-\\u0F7D\\u0F80\\u0F82-\\u0F84\\u0F86\\u0F87\\u0FC6\\u1037\\u1039\\u103A\\u108D\\u135D-\\u135F\\u1714\\u17D2\\u17DD\\u18A9\\u1939-\\u193B\\u1A17\\u1A18\\u1A60\\u1A75-\\u1A7C\\u1A7F\\u1AB0-\\u1ABD\\u1ABF-\\u1ACE\\u1B34\\u1B6B-\\u1B73\\u1BAB\\u1BE6\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1CF4\\u1CF8\\u1CF9\\u1DC0-\\u1DFF\\u200D\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2CEF-\\u2CF1\\u2D7F\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F\\uA674-\\uA67D\\uA69E\\uA69F\\uA6F0\\uA6F1\\uA806\\uA82C\\uA8C4\\uA8E0-\\uA8F1\\uA92B-\\uA92D\\uA9B3\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAF6\\uABED\\uFB1E\\uFE20-\\uFE2F]|\\uD800[\\uDDFD\\uDEE0\\uDF76-\\uDF7A]|\\uD802[\\uDE0D\\uDE0F\\uDE38-\\uDE3A\\uDE3F\\uDEE5\\uDEE6]|\\uD803[\\uDD24-\\uDD27\\uDEAB\\uDEAC\\uDEFD-\\uDEFF\\uDF46-\\uDF50\\uDF82-\\uDF85]|\\uD804[\\uDC46\\uDC70\\uDC7F\\uDCB9\\uDCBA\\uDD00-\\uDD02\\uDD33\\uDD34\\uDD73\\uDDCA\\uDE36\\uDEE9\\uDEEA\\uDF3B\\uDF3C\\uDF66-\\uDF6C\\uDF70-\\uDF74]|\\uD805[\\uDC42\\uDC46\\uDC5E\\uDCC2\\uDCC3\\uDDBF\\uDDC0\\uDE3F\\uDEB7\\uDF2B]|\\uD806[\\uDC39\\uDC3A\\uDD3E\\uDD43\\uDDE0\\uDE34\\uDE47\\uDE99]|\\uD807[\\uDC3F\\uDD42\\uDD44\\uDD45\\uDD97\\uDF42]|\\uD81A[\\uDEF0-\\uDEF4\\uDF30-\\uDF36]|\\uD82F\\uDC9E|\\uD834[\\uDD65\\uDD67-\\uDD69\\uDD6E-\\uDD72\\uDD7B-\\uDD82\\uDD85-\\uDD8B\\uDDAA-\\uDDAD\\uDE42-\\uDE44]|\\uD838[\\uDC00-\\uDC06\\uDC08-\\uDC18\\uDC1B-\\uDC21\\uDC23\\uDC24\\uDC26-\\uDC2A\\uDC8F\\uDD30-\\uDD36\\uDEAE\\uDEEC-\\uDEEF]|\\uD839[\\uDCEC-\\uDCEF]|\\uD83A[\\uDCD0-\\uDCD6\\uDD44-\\uDD4A])", - "$ExtPict": "(?:[\\xA9\\xAE\\u203C\\u2049\\u2122\\u2139\\u2194-\\u2199\\u21A9\\u21AA\\u231A\\u231B\\u2328\\u2388\\u23CF\\u23E9-\\u23F3\\u23F8-\\u23FA\\u24C2\\u25AA\\u25AB\\u25B6\\u25C0\\u25FB-\\u25FE\\u2600-\\u2605\\u2607-\\u2612\\u2614-\\u2685\\u2690-\\u2705\\u2708-\\u2712\\u2714\\u2716\\u271D\\u2721\\u2728\\u2733\\u2734\\u2744\\u2747\\u274C\\u274E\\u2753-\\u2755\\u2757\\u2763-\\u2767\\u2795-\\u2797\\u27A1\\u27B0\\u27BF\\u2934\\u2935\\u2B05-\\u2B07\\u2B1B\\u2B1C\\u2B50\\u2B55\\u3030\\u303D\\u3297\\u3299]|\\uD83C[\\uDC00-\\uDCFF\\uDD0D-\\uDD0F\\uDD2F\\uDD6C-\\uDD71\\uDD7E\\uDD7F\\uDD8E\\uDD91-\\uDD9A\\uDDAD-\\uDDE5\\uDE01-\\uDE0F\\uDE1A\\uDE2F\\uDE32-\\uDE3A\\uDE3C-\\uDE3F\\uDE49-\\uDFFA]|\\uD83D[\\uDC00-\\uDD3D\\uDD46-\\uDE4F\\uDE80-\\uDEFF\\uDF74-\\uDF7F\\uDFD5-\\uDFFF]|\\uD83E[\\uDC0C-\\uDC0F\\uDC48-\\uDC4F\\uDC5A-\\uDC5F\\uDC88-\\uDC8F\\uDCAE-\\uDCFF\\uDD0C-\\uDD3A\\uDD3C-\\uDD45\\uDD47-\\uDEFF]|\\uD83F[\\uDC00-\\uDFFD])", - "$Extend": "(?:[\\u0300-\\u036F\\u0483-\\u0489\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065F\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u07FD\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0859-\\u085B\\u0898-\\u089F\\u08CA-\\u08E1\\u08E3-\\u0902\\u093A\\u093C\\u0941-\\u0948\\u094D\\u0951-\\u0957\\u0962\\u0963\\u0981\\u09BC\\u09BE\\u09C1-\\u09C4\\u09CD\\u09D7\\u09E2\\u09E3\\u09FE\\u0A01\\u0A02\\u0A3C\\u0A41\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81\\u0A82\\u0ABC\\u0AC1-\\u0AC5\\u0AC7\\u0AC8\\u0ACD\\u0AE2\\u0AE3\\u0AFA-\\u0AFF\\u0B01\\u0B3C\\u0B3E\\u0B3F\\u0B41-\\u0B44\\u0B4D\\u0B55-\\u0B57\\u0B62\\u0B63\\u0B82\\u0BBE\\u0BC0\\u0BCD\\u0BD7\\u0C00\\u0C04\\u0C3C\\u0C3E-\\u0C40\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0C81\\u0CBC\\u0CBF\\u0CC2\\u0CC6\\u0CCC\\u0CCD\\u0CD5\\u0CD6\\u0CE2\\u0CE3\\u0D00\\u0D01\\u0D3B\\u0D3C\\u0D3E\\u0D41-\\u0D44\\u0D4D\\u0D57\\u0D62\\u0D63\\u0D81\\u0DCA\\u0DCF\\u0DD2-\\u0DD4\\u0DD6\\u0DDF\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EBC\\u0EC8-\\u0ECE\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71-\\u0F7E\\u0F80-\\u0F84\\u0F86\\u0F87\\u0F8D-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102D-\\u1030\\u1032-\\u1037\\u1039\\u103A\\u103D\\u103E\\u1058\\u1059\\u105E-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108D\\u109D\\u135D-\\u135F\\u1712-\\u1714\\u1732\\u1733\\u1752\\u1753\\u1772\\u1773\\u17B4\\u17B5\\u17B7-\\u17BD\\u17C6\\u17C9-\\u17D3\\u17DD\\u180B-\\u180D\\u180F\\u1885\\u1886\\u18A9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193B\\u1A17\\u1A18\\u1A1B\\u1A56\\u1A58-\\u1A5E\\u1A60\\u1A62\\u1A65-\\u1A6C\\u1A73-\\u1A7C\\u1A7F\\u1AB0-\\u1ACE\\u1B00-\\u1B03\\u1B34-\\u1B3A\\u1B3C\\u1B42\\u1B6B-\\u1B73\\u1B80\\u1B81\\u1BA2-\\u1BA5\\u1BA8\\u1BA9\\u1BAB-\\u1BAD\\u1BE6\\u1BE8\\u1BE9\\u1BED\\u1BEF-\\u1BF1\\u1C2C-\\u1C33\\u1C36\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1CF4\\u1CF8\\u1CF9\\u1DC0-\\u1DFF\\u200C\\u20D0-\\u20F0\\u2CEF-\\u2CF1\\u2D7F\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F-\\uA672\\uA674-\\uA67D\\uA69E\\uA69F\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA825\\uA826\\uA82C\\uA8C4\\uA8C5\\uA8E0-\\uA8F1\\uA8FF\\uA926-\\uA92D\\uA947-\\uA951\\uA980-\\uA982\\uA9B3\\uA9B6-\\uA9B9\\uA9BC\\uA9BD\\uA9E5\\uAA29-\\uAA2E\\uAA31\\uAA32\\uAA35\\uAA36\\uAA43\\uAA4C\\uAA7C\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAEC\\uAAED\\uAAF6\\uABE5\\uABE8\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE2F\\uFF9E\\uFF9F]|\\uD800[\\uDDFD\\uDEE0\\uDF76-\\uDF7A]|\\uD802[\\uDE01-\\uDE03\\uDE05\\uDE06\\uDE0C-\\uDE0F\\uDE38-\\uDE3A\\uDE3F\\uDEE5\\uDEE6]|\\uD803[\\uDD24-\\uDD27\\uDEAB\\uDEAC\\uDEFD-\\uDEFF\\uDF46-\\uDF50\\uDF82-\\uDF85]|\\uD804[\\uDC01\\uDC38-\\uDC46\\uDC70\\uDC73\\uDC74\\uDC7F-\\uDC81\\uDCB3-\\uDCB6\\uDCB9\\uDCBA\\uDCC2\\uDD00-\\uDD02\\uDD27-\\uDD2B\\uDD2D-\\uDD34\\uDD73\\uDD80\\uDD81\\uDDB6-\\uDDBE\\uDDC9-\\uDDCC\\uDDCF\\uDE2F-\\uDE31\\uDE34\\uDE36\\uDE37\\uDE3E\\uDE41\\uDEDF\\uDEE3-\\uDEEA\\uDF00\\uDF01\\uDF3B\\uDF3C\\uDF3E\\uDF40\\uDF57\\uDF66-\\uDF6C\\uDF70-\\uDF74]|\\uD805[\\uDC38-\\uDC3F\\uDC42-\\uDC44\\uDC46\\uDC5E\\uDCB0\\uDCB3-\\uDCB8\\uDCBA\\uDCBD\\uDCBF\\uDCC0\\uDCC2\\uDCC3\\uDDAF\\uDDB2-\\uDDB5\\uDDBC\\uDDBD\\uDDBF\\uDDC0\\uDDDC\\uDDDD\\uDE33-\\uDE3A\\uDE3D\\uDE3F\\uDE40\\uDEAB\\uDEAD\\uDEB0-\\uDEB5\\uDEB7\\uDF1D-\\uDF1F\\uDF22-\\uDF25\\uDF27-\\uDF2B]|\\uD806[\\uDC2F-\\uDC37\\uDC39\\uDC3A\\uDD30\\uDD3B\\uDD3C\\uDD3E\\uDD43\\uDDD4-\\uDDD7\\uDDDA\\uDDDB\\uDDE0\\uDE01-\\uDE0A\\uDE33-\\uDE38\\uDE3B-\\uDE3E\\uDE47\\uDE51-\\uDE56\\uDE59-\\uDE5B\\uDE8A-\\uDE96\\uDE98\\uDE99]|\\uD807[\\uDC30-\\uDC36\\uDC38-\\uDC3D\\uDC3F\\uDC92-\\uDCA7\\uDCAA-\\uDCB0\\uDCB2\\uDCB3\\uDCB5\\uDCB6\\uDD31-\\uDD36\\uDD3A\\uDD3C\\uDD3D\\uDD3F-\\uDD45\\uDD47\\uDD90\\uDD91\\uDD95\\uDD97\\uDEF3\\uDEF4\\uDF00\\uDF01\\uDF36-\\uDF3A\\uDF40\\uDF42]|\\uD80D[\\uDC40\\uDC47-\\uDC55]|\\uD81A[\\uDEF0-\\uDEF4\\uDF30-\\uDF36]|\\uD81B[\\uDF4F\\uDF8F-\\uDF92\\uDFE4]|\\uD82F[\\uDC9D\\uDC9E]|\\uD833[\\uDF00-\\uDF2D\\uDF30-\\uDF46]|\\uD834[\\uDD65\\uDD67-\\uDD69\\uDD6E-\\uDD72\\uDD7B-\\uDD82\\uDD85-\\uDD8B\\uDDAA-\\uDDAD\\uDE42-\\uDE44]|\\uD836[\\uDE00-\\uDE36\\uDE3B-\\uDE6C\\uDE75\\uDE84\\uDE9B-\\uDE9F\\uDEA1-\\uDEAF]|\\uD838[\\uDC00-\\uDC06\\uDC08-\\uDC18\\uDC1B-\\uDC21\\uDC23\\uDC24\\uDC26-\\uDC2A\\uDC8F\\uDD30-\\uDD36\\uDEAE\\uDEEC-\\uDEEF]|\\uD839[\\uDCEC-\\uDCEF]|\\uD83A[\\uDCD0-\\uDCD6\\uDD44-\\uDD4A]|\\uD83C[\\uDFFB-\\uDFFF]|\\uDB40[\\uDC20-\\uDC7F\\uDD00-\\uDDEF])", - "$L": "[\\u1100-\\u115F\\uA960-\\uA97C]", - "$LF": "\\n", - "$LV": "[\\uAC00\\uAC1C\\uAC38\\uAC54\\uAC70\\uAC8C\\uACA8\\uACC4\\uACE0\\uACFC\\uAD18\\uAD34\\uAD50\\uAD6C\\uAD88\\uADA4\\uADC0\\uADDC\\uADF8\\uAE14\\uAE30\\uAE4C\\uAE68\\uAE84\\uAEA0\\uAEBC\\uAED8\\uAEF4\\uAF10\\uAF2C\\uAF48\\uAF64\\uAF80\\uAF9C\\uAFB8\\uAFD4\\uAFF0\\uB00C\\uB028\\uB044\\uB060\\uB07C\\uB098\\uB0B4\\uB0D0\\uB0EC\\uB108\\uB124\\uB140\\uB15C\\uB178\\uB194\\uB1B0\\uB1CC\\uB1E8\\uB204\\uB220\\uB23C\\uB258\\uB274\\uB290\\uB2AC\\uB2C8\\uB2E4\\uB300\\uB31C\\uB338\\uB354\\uB370\\uB38C\\uB3A8\\uB3C4\\uB3E0\\uB3FC\\uB418\\uB434\\uB450\\uB46C\\uB488\\uB4A4\\uB4C0\\uB4DC\\uB4F8\\uB514\\uB530\\uB54C\\uB568\\uB584\\uB5A0\\uB5BC\\uB5D8\\uB5F4\\uB610\\uB62C\\uB648\\uB664\\uB680\\uB69C\\uB6B8\\uB6D4\\uB6F0\\uB70C\\uB728\\uB744\\uB760\\uB77C\\uB798\\uB7B4\\uB7D0\\uB7EC\\uB808\\uB824\\uB840\\uB85C\\uB878\\uB894\\uB8B0\\uB8CC\\uB8E8\\uB904\\uB920\\uB93C\\uB958\\uB974\\uB990\\uB9AC\\uB9C8\\uB9E4\\uBA00\\uBA1C\\uBA38\\uBA54\\uBA70\\uBA8C\\uBAA8\\uBAC4\\uBAE0\\uBAFC\\uBB18\\uBB34\\uBB50\\uBB6C\\uBB88\\uBBA4\\uBBC0\\uBBDC\\uBBF8\\uBC14\\uBC30\\uBC4C\\uBC68\\uBC84\\uBCA0\\uBCBC\\uBCD8\\uBCF4\\uBD10\\uBD2C\\uBD48\\uBD64\\uBD80\\uBD9C\\uBDB8\\uBDD4\\uBDF0\\uBE0C\\uBE28\\uBE44\\uBE60\\uBE7C\\uBE98\\uBEB4\\uBED0\\uBEEC\\uBF08\\uBF24\\uBF40\\uBF5C\\uBF78\\uBF94\\uBFB0\\uBFCC\\uBFE8\\uC004\\uC020\\uC03C\\uC058\\uC074\\uC090\\uC0AC\\uC0C8\\uC0E4\\uC100\\uC11C\\uC138\\uC154\\uC170\\uC18C\\uC1A8\\uC1C4\\uC1E0\\uC1FC\\uC218\\uC234\\uC250\\uC26C\\uC288\\uC2A4\\uC2C0\\uC2DC\\uC2F8\\uC314\\uC330\\uC34C\\uC368\\uC384\\uC3A0\\uC3BC\\uC3D8\\uC3F4\\uC410\\uC42C\\uC448\\uC464\\uC480\\uC49C\\uC4B8\\uC4D4\\uC4F0\\uC50C\\uC528\\uC544\\uC560\\uC57C\\uC598\\uC5B4\\uC5D0\\uC5EC\\uC608\\uC624\\uC640\\uC65C\\uC678\\uC694\\uC6B0\\uC6CC\\uC6E8\\uC704\\uC720\\uC73C\\uC758\\uC774\\uC790\\uC7AC\\uC7C8\\uC7E4\\uC800\\uC81C\\uC838\\uC854\\uC870\\uC88C\\uC8A8\\uC8C4\\uC8E0\\uC8FC\\uC918\\uC934\\uC950\\uC96C\\uC988\\uC9A4\\uC9C0\\uC9DC\\uC9F8\\uCA14\\uCA30\\uCA4C\\uCA68\\uCA84\\uCAA0\\uCABC\\uCAD8\\uCAF4\\uCB10\\uCB2C\\uCB48\\uCB64\\uCB80\\uCB9C\\uCBB8\\uCBD4\\uCBF0\\uCC0C\\uCC28\\uCC44\\uCC60\\uCC7C\\uCC98\\uCCB4\\uCCD0\\uCCEC\\uCD08\\uCD24\\uCD40\\uCD5C\\uCD78\\uCD94\\uCDB0\\uCDCC\\uCDE8\\uCE04\\uCE20\\uCE3C\\uCE58\\uCE74\\uCE90\\uCEAC\\uCEC8\\uCEE4\\uCF00\\uCF1C\\uCF38\\uCF54\\uCF70\\uCF8C\\uCFA8\\uCFC4\\uCFE0\\uCFFC\\uD018\\uD034\\uD050\\uD06C\\uD088\\uD0A4\\uD0C0\\uD0DC\\uD0F8\\uD114\\uD130\\uD14C\\uD168\\uD184\\uD1A0\\uD1BC\\uD1D8\\uD1F4\\uD210\\uD22C\\uD248\\uD264\\uD280\\uD29C\\uD2B8\\uD2D4\\uD2F0\\uD30C\\uD328\\uD344\\uD360\\uD37C\\uD398\\uD3B4\\uD3D0\\uD3EC\\uD408\\uD424\\uD440\\uD45C\\uD478\\uD494\\uD4B0\\uD4CC\\uD4E8\\uD504\\uD520\\uD53C\\uD558\\uD574\\uD590\\uD5AC\\uD5C8\\uD5E4\\uD600\\uD61C\\uD638\\uD654\\uD670\\uD68C\\uD6A8\\uD6C4\\uD6E0\\uD6FC\\uD718\\uD734\\uD750\\uD76C\\uD788]", - "$LVT": "[\\uAC01-\\uAC1B\\uAC1D-\\uAC37\\uAC39-\\uAC53\\uAC55-\\uAC6F\\uAC71-\\uAC8B\\uAC8D-\\uACA7\\uACA9-\\uACC3\\uACC5-\\uACDF\\uACE1-\\uACFB\\uACFD-\\uAD17\\uAD19-\\uAD33\\uAD35-\\uAD4F\\uAD51-\\uAD6B\\uAD6D-\\uAD87\\uAD89-\\uADA3\\uADA5-\\uADBF\\uADC1-\\uADDB\\uADDD-\\uADF7\\uADF9-\\uAE13\\uAE15-\\uAE2F\\uAE31-\\uAE4B\\uAE4D-\\uAE67\\uAE69-\\uAE83\\uAE85-\\uAE9F\\uAEA1-\\uAEBB\\uAEBD-\\uAED7\\uAED9-\\uAEF3\\uAEF5-\\uAF0F\\uAF11-\\uAF2B\\uAF2D-\\uAF47\\uAF49-\\uAF63\\uAF65-\\uAF7F\\uAF81-\\uAF9B\\uAF9D-\\uAFB7\\uAFB9-\\uAFD3\\uAFD5-\\uAFEF\\uAFF1-\\uB00B\\uB00D-\\uB027\\uB029-\\uB043\\uB045-\\uB05F\\uB061-\\uB07B\\uB07D-\\uB097\\uB099-\\uB0B3\\uB0B5-\\uB0CF\\uB0D1-\\uB0EB\\uB0ED-\\uB107\\uB109-\\uB123\\uB125-\\uB13F\\uB141-\\uB15B\\uB15D-\\uB177\\uB179-\\uB193\\uB195-\\uB1AF\\uB1B1-\\uB1CB\\uB1CD-\\uB1E7\\uB1E9-\\uB203\\uB205-\\uB21F\\uB221-\\uB23B\\uB23D-\\uB257\\uB259-\\uB273\\uB275-\\uB28F\\uB291-\\uB2AB\\uB2AD-\\uB2C7\\uB2C9-\\uB2E3\\uB2E5-\\uB2FF\\uB301-\\uB31B\\uB31D-\\uB337\\uB339-\\uB353\\uB355-\\uB36F\\uB371-\\uB38B\\uB38D-\\uB3A7\\uB3A9-\\uB3C3\\uB3C5-\\uB3DF\\uB3E1-\\uB3FB\\uB3FD-\\uB417\\uB419-\\uB433\\uB435-\\uB44F\\uB451-\\uB46B\\uB46D-\\uB487\\uB489-\\uB4A3\\uB4A5-\\uB4BF\\uB4C1-\\uB4DB\\uB4DD-\\uB4F7\\uB4F9-\\uB513\\uB515-\\uB52F\\uB531-\\uB54B\\uB54D-\\uB567\\uB569-\\uB583\\uB585-\\uB59F\\uB5A1-\\uB5BB\\uB5BD-\\uB5D7\\uB5D9-\\uB5F3\\uB5F5-\\uB60F\\uB611-\\uB62B\\uB62D-\\uB647\\uB649-\\uB663\\uB665-\\uB67F\\uB681-\\uB69B\\uB69D-\\uB6B7\\uB6B9-\\uB6D3\\uB6D5-\\uB6EF\\uB6F1-\\uB70B\\uB70D-\\uB727\\uB729-\\uB743\\uB745-\\uB75F\\uB761-\\uB77B\\uB77D-\\uB797\\uB799-\\uB7B3\\uB7B5-\\uB7CF\\uB7D1-\\uB7EB\\uB7ED-\\uB807\\uB809-\\uB823\\uB825-\\uB83F\\uB841-\\uB85B\\uB85D-\\uB877\\uB879-\\uB893\\uB895-\\uB8AF\\uB8B1-\\uB8CB\\uB8CD-\\uB8E7\\uB8E9-\\uB903\\uB905-\\uB91F\\uB921-\\uB93B\\uB93D-\\uB957\\uB959-\\uB973\\uB975-\\uB98F\\uB991-\\uB9AB\\uB9AD-\\uB9C7\\uB9C9-\\uB9E3\\uB9E5-\\uB9FF\\uBA01-\\uBA1B\\uBA1D-\\uBA37\\uBA39-\\uBA53\\uBA55-\\uBA6F\\uBA71-\\uBA8B\\uBA8D-\\uBAA7\\uBAA9-\\uBAC3\\uBAC5-\\uBADF\\uBAE1-\\uBAFB\\uBAFD-\\uBB17\\uBB19-\\uBB33\\uBB35-\\uBB4F\\uBB51-\\uBB6B\\uBB6D-\\uBB87\\uBB89-\\uBBA3\\uBBA5-\\uBBBF\\uBBC1-\\uBBDB\\uBBDD-\\uBBF7\\uBBF9-\\uBC13\\uBC15-\\uBC2F\\uBC31-\\uBC4B\\uBC4D-\\uBC67\\uBC69-\\uBC83\\uBC85-\\uBC9F\\uBCA1-\\uBCBB\\uBCBD-\\uBCD7\\uBCD9-\\uBCF3\\uBCF5-\\uBD0F\\uBD11-\\uBD2B\\uBD2D-\\uBD47\\uBD49-\\uBD63\\uBD65-\\uBD7F\\uBD81-\\uBD9B\\uBD9D-\\uBDB7\\uBDB9-\\uBDD3\\uBDD5-\\uBDEF\\uBDF1-\\uBE0B\\uBE0D-\\uBE27\\uBE29-\\uBE43\\uBE45-\\uBE5F\\uBE61-\\uBE7B\\uBE7D-\\uBE97\\uBE99-\\uBEB3\\uBEB5-\\uBECF\\uBED1-\\uBEEB\\uBEED-\\uBF07\\uBF09-\\uBF23\\uBF25-\\uBF3F\\uBF41-\\uBF5B\\uBF5D-\\uBF77\\uBF79-\\uBF93\\uBF95-\\uBFAF\\uBFB1-\\uBFCB\\uBFCD-\\uBFE7\\uBFE9-\\uC003\\uC005-\\uC01F\\uC021-\\uC03B\\uC03D-\\uC057\\uC059-\\uC073\\uC075-\\uC08F\\uC091-\\uC0AB\\uC0AD-\\uC0C7\\uC0C9-\\uC0E3\\uC0E5-\\uC0FF\\uC101-\\uC11B\\uC11D-\\uC137\\uC139-\\uC153\\uC155-\\uC16F\\uC171-\\uC18B\\uC18D-\\uC1A7\\uC1A9-\\uC1C3\\uC1C5-\\uC1DF\\uC1E1-\\uC1FB\\uC1FD-\\uC217\\uC219-\\uC233\\uC235-\\uC24F\\uC251-\\uC26B\\uC26D-\\uC287\\uC289-\\uC2A3\\uC2A5-\\uC2BF\\uC2C1-\\uC2DB\\uC2DD-\\uC2F7\\uC2F9-\\uC313\\uC315-\\uC32F\\uC331-\\uC34B\\uC34D-\\uC367\\uC369-\\uC383\\uC385-\\uC39F\\uC3A1-\\uC3BB\\uC3BD-\\uC3D7\\uC3D9-\\uC3F3\\uC3F5-\\uC40F\\uC411-\\uC42B\\uC42D-\\uC447\\uC449-\\uC463\\uC465-\\uC47F\\uC481-\\uC49B\\uC49D-\\uC4B7\\uC4B9-\\uC4D3\\uC4D5-\\uC4EF\\uC4F1-\\uC50B\\uC50D-\\uC527\\uC529-\\uC543\\uC545-\\uC55F\\uC561-\\uC57B\\uC57D-\\uC597\\uC599-\\uC5B3\\uC5B5-\\uC5CF\\uC5D1-\\uC5EB\\uC5ED-\\uC607\\uC609-\\uC623\\uC625-\\uC63F\\uC641-\\uC65B\\uC65D-\\uC677\\uC679-\\uC693\\uC695-\\uC6AF\\uC6B1-\\uC6CB\\uC6CD-\\uC6E7\\uC6E9-\\uC703\\uC705-\\uC71F\\uC721-\\uC73B\\uC73D-\\uC757\\uC759-\\uC773\\uC775-\\uC78F\\uC791-\\uC7AB\\uC7AD-\\uC7C7\\uC7C9-\\uC7E3\\uC7E5-\\uC7FF\\uC801-\\uC81B\\uC81D-\\uC837\\uC839-\\uC853\\uC855-\\uC86F\\uC871-\\uC88B\\uC88D-\\uC8A7\\uC8A9-\\uC8C3\\uC8C5-\\uC8DF\\uC8E1-\\uC8FB\\uC8FD-\\uC917\\uC919-\\uC933\\uC935-\\uC94F\\uC951-\\uC96B\\uC96D-\\uC987\\uC989-\\uC9A3\\uC9A5-\\uC9BF\\uC9C1-\\uC9DB\\uC9DD-\\uC9F7\\uC9F9-\\uCA13\\uCA15-\\uCA2F\\uCA31-\\uCA4B\\uCA4D-\\uCA67\\uCA69-\\uCA83\\uCA85-\\uCA9F\\uCAA1-\\uCABB\\uCABD-\\uCAD7\\uCAD9-\\uCAF3\\uCAF5-\\uCB0F\\uCB11-\\uCB2B\\uCB2D-\\uCB47\\uCB49-\\uCB63\\uCB65-\\uCB7F\\uCB81-\\uCB9B\\uCB9D-\\uCBB7\\uCBB9-\\uCBD3\\uCBD5-\\uCBEF\\uCBF1-\\uCC0B\\uCC0D-\\uCC27\\uCC29-\\uCC43\\uCC45-\\uCC5F\\uCC61-\\uCC7B\\uCC7D-\\uCC97\\uCC99-\\uCCB3\\uCCB5-\\uCCCF\\uCCD1-\\uCCEB\\uCCED-\\uCD07\\uCD09-\\uCD23\\uCD25-\\uCD3F\\uCD41-\\uCD5B\\uCD5D-\\uCD77\\uCD79-\\uCD93\\uCD95-\\uCDAF\\uCDB1-\\uCDCB\\uCDCD-\\uCDE7\\uCDE9-\\uCE03\\uCE05-\\uCE1F\\uCE21-\\uCE3B\\uCE3D-\\uCE57\\uCE59-\\uCE73\\uCE75-\\uCE8F\\uCE91-\\uCEAB\\uCEAD-\\uCEC7\\uCEC9-\\uCEE3\\uCEE5-\\uCEFF\\uCF01-\\uCF1B\\uCF1D-\\uCF37\\uCF39-\\uCF53\\uCF55-\\uCF6F\\uCF71-\\uCF8B\\uCF8D-\\uCFA7\\uCFA9-\\uCFC3\\uCFC5-\\uCFDF\\uCFE1-\\uCFFB\\uCFFD-\\uD017\\uD019-\\uD033\\uD035-\\uD04F\\uD051-\\uD06B\\uD06D-\\uD087\\uD089-\\uD0A3\\uD0A5-\\uD0BF\\uD0C1-\\uD0DB\\uD0DD-\\uD0F7\\uD0F9-\\uD113\\uD115-\\uD12F\\uD131-\\uD14B\\uD14D-\\uD167\\uD169-\\uD183\\uD185-\\uD19F\\uD1A1-\\uD1BB\\uD1BD-\\uD1D7\\uD1D9-\\uD1F3\\uD1F5-\\uD20F\\uD211-\\uD22B\\uD22D-\\uD247\\uD249-\\uD263\\uD265-\\uD27F\\uD281-\\uD29B\\uD29D-\\uD2B7\\uD2B9-\\uD2D3\\uD2D5-\\uD2EF\\uD2F1-\\uD30B\\uD30D-\\uD327\\uD329-\\uD343\\uD345-\\uD35F\\uD361-\\uD37B\\uD37D-\\uD397\\uD399-\\uD3B3\\uD3B5-\\uD3CF\\uD3D1-\\uD3EB\\uD3ED-\\uD407\\uD409-\\uD423\\uD425-\\uD43F\\uD441-\\uD45B\\uD45D-\\uD477\\uD479-\\uD493\\uD495-\\uD4AF\\uD4B1-\\uD4CB\\uD4CD-\\uD4E7\\uD4E9-\\uD503\\uD505-\\uD51F\\uD521-\\uD53B\\uD53D-\\uD557\\uD559-\\uD573\\uD575-\\uD58F\\uD591-\\uD5AB\\uD5AD-\\uD5C7\\uD5C9-\\uD5E3\\uD5E5-\\uD5FF\\uD601-\\uD61B\\uD61D-\\uD637\\uD639-\\uD653\\uD655-\\uD66F\\uD671-\\uD68B\\uD68D-\\uD6A7\\uD6A9-\\uD6C3\\uD6C5-\\uD6DF\\uD6E1-\\uD6FB\\uD6FD-\\uD717\\uD719-\\uD733\\uD735-\\uD74F\\uD751-\\uD76B\\uD76D-\\uD787\\uD789-\\uD7A3]", - "$LinkingConsonant": "[\\u0915-\\u0939\\u0958-\\u095F\\u0978-\\u097F\\u0995-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09DC\\u09DD\\u09DF\\u09F0\\u09F1\\u0A95-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0AF9\\u0B15-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B5C\\u0B5D\\u0B5F\\u0B71\\u0C15-\\u0C28\\u0C2A-\\u0C39\\u0C58-\\u0C5A\\u0D15-\\u0D3A]", - "$Prepend": "(?:[\\u0600-\\u0605\\u06DD\\u070F\\u0890\\u0891\\u08E2\\u0D4E]|\\uD804[\\uDCBD\\uDCCD\\uDDC2\\uDDC3]|\\uD806[\\uDD3F\\uDD41\\uDE3A\\uDE84-\\uDE89]|\\uD807[\\uDD46\\uDF02])", - "$RI": "(?:\\uD83C[\\uDDE6-\\uDDFF])", - "$SpacingMark": "(?:[\\u0903\\u093B\\u093E-\\u0940\\u0949-\\u094C\\u094E\\u094F\\u0982\\u0983\\u09BF\\u09C0\\u09C7\\u09C8\\u09CB\\u09CC\\u0A03\\u0A3E-\\u0A40\\u0A83\\u0ABE-\\u0AC0\\u0AC9\\u0ACB\\u0ACC\\u0B02\\u0B03\\u0B40\\u0B47\\u0B48\\u0B4B\\u0B4C\\u0BBF\\u0BC1\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCC\\u0C01-\\u0C03\\u0C41-\\u0C44\\u0C82\\u0C83\\u0CBE\\u0CC0\\u0CC1\\u0CC3\\u0CC4\\u0CC7\\u0CC8\\u0CCA\\u0CCB\\u0CF3\\u0D02\\u0D03\\u0D3F\\u0D40\\u0D46-\\u0D48\\u0D4A-\\u0D4C\\u0D82\\u0D83\\u0DD0\\u0DD1\\u0DD8-\\u0DDE\\u0DF2\\u0DF3\\u0E33\\u0EB3\\u0F3E\\u0F3F\\u0F7F\\u1031\\u103B\\u103C\\u1056\\u1057\\u1084\\u1715\\u1734\\u17B6\\u17BE-\\u17C5\\u17C7\\u17C8\\u1923-\\u1926\\u1929-\\u192B\\u1930\\u1931\\u1933-\\u1938\\u1A19\\u1A1A\\u1A55\\u1A57\\u1A6D-\\u1A72\\u1B04\\u1B3B\\u1B3D-\\u1B41\\u1B43\\u1B44\\u1B82\\u1BA1\\u1BA6\\u1BA7\\u1BAA\\u1BE7\\u1BEA-\\u1BEC\\u1BEE\\u1BF2\\u1BF3\\u1C24-\\u1C2B\\u1C34\\u1C35\\u1CE1\\u1CF7\\uA823\\uA824\\uA827\\uA880\\uA881\\uA8B4-\\uA8C3\\uA952\\uA953\\uA983\\uA9B4\\uA9B5\\uA9BA\\uA9BB\\uA9BE-\\uA9C0\\uAA2F\\uAA30\\uAA33\\uAA34\\uAA4D\\uAAEB\\uAAEE\\uAAEF\\uAAF5\\uABE3\\uABE4\\uABE6\\uABE7\\uABE9\\uABEA\\uABEC]|\\uD804[\\uDC00\\uDC02\\uDC82\\uDCB0-\\uDCB2\\uDCB7\\uDCB8\\uDD2C\\uDD45\\uDD46\\uDD82\\uDDB3-\\uDDB5\\uDDBF\\uDDC0\\uDDCE\\uDE2C-\\uDE2E\\uDE32\\uDE33\\uDE35\\uDEE0-\\uDEE2\\uDF02\\uDF03\\uDF3F\\uDF41-\\uDF44\\uDF47\\uDF48\\uDF4B-\\uDF4D\\uDF62\\uDF63]|\\uD805[\\uDC35-\\uDC37\\uDC40\\uDC41\\uDC45\\uDCB1\\uDCB2\\uDCB9\\uDCBB\\uDCBC\\uDCBE\\uDCC1\\uDDB0\\uDDB1\\uDDB8-\\uDDBB\\uDDBE\\uDE30-\\uDE32\\uDE3B\\uDE3C\\uDE3E\\uDEAC\\uDEAE\\uDEAF\\uDEB6\\uDF26]|\\uD806[\\uDC2C-\\uDC2E\\uDC38\\uDD31-\\uDD35\\uDD37\\uDD38\\uDD3D\\uDD40\\uDD42\\uDDD1-\\uDDD3\\uDDDC-\\uDDDF\\uDDE4\\uDE39\\uDE57\\uDE58\\uDE97]|\\uD807[\\uDC2F\\uDC3E\\uDCA9\\uDCB1\\uDCB4\\uDD8A-\\uDD8E\\uDD93\\uDD94\\uDD96\\uDEF5\\uDEF6\\uDF03\\uDF34\\uDF35\\uDF3E\\uDF3F\\uDF41]|\\uD81B[\\uDF51-\\uDF87\\uDFF0\\uDFF1]|\\uD834[\\uDD66\\uDD6D])", - "$T": "[\\u11A8-\\u11FF\\uD7CB-\\uD7FB]", - "$V": "[\\u1160-\\u11A7\\uD7B0-\\uD7C6]", - "$Virama": "[\\u094D\\u09CD\\u0ACD\\u0B4D\\u0C4D\\u0D4D]", - "$ZWJ": "\\u200D" - } -} diff --git a/src/mono/browser/runtime/loader/assets.ts b/src/mono/browser/runtime/loader/assets.ts index 50bc98ef0217f..e749fb42afb78 100644 --- a/src/mono/browser/runtime/loader/assets.ts +++ b/src/mono/browser/runtime/loader/assets.ts @@ -4,7 +4,7 @@ import WasmEnableThreads from "consts:wasmEnableThreads"; import { PThreadPtrNull, type AssetEntryInternal, type PThreadWorker, type PromiseAndController } from "../types/internal"; -import { GlobalizationMode, type AssetBehaviors, type AssetEntry, type LoadingResource, type ResourceList, type SingleAssetBehaviors as SingleAssetBehaviors, type WebAssemblyBootResourceType } from "../types"; +import { type AssetBehaviors, type AssetEntry, type LoadingResource, type ResourceList, type SingleAssetBehaviors as SingleAssetBehaviors, type WebAssemblyBootResourceType } from "../types"; import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, ENVIRONMENT_IS_WEB, ENVIRONMENT_IS_WORKER, loaderHelpers, mono_assert, runtimeHelpers } from "./globals"; import { createPromiseController } from "./promise-controller"; import { mono_log_debug, mono_log_warn } from "./logging"; @@ -29,7 +29,6 @@ const jsRuntimeModulesAssetTypes: { [k: string]: boolean } = { "js-module-threads": true, - "js-module-globalization": true, "js-module-runtime": true, "js-module-dotnet": true, "js-module-native": true, @@ -72,8 +71,7 @@ const skipBufferByAssetTypes: { [k: string]: boolean } = { "dotnetwasm": true, - "symbols": true, - "segmentation-rules": true, + "symbols": true }; // these assets are instantiated differently than the main flow @@ -82,8 +80,7 @@ const skipInstantiateByAssetTypes: { } = { ...jsModulesAssetTypes, "dotnetwasm": true, - "symbols": true, - "segmentation-rules": true, + "symbols": true }; // load again for each worker @@ -91,7 +88,6 @@ const loadIntoWorker: { [k: string]: boolean } = { "symbols": true, - "segmentation-rules": true, }; export function shouldLoadIcuAsset (asset: AssetEntryInternal): boolean { @@ -223,9 +219,6 @@ export async function mono_download_assets (): Promise { if (asset.behavior === "symbols") { await runtimeHelpers.instantiate_symbols_asset(asset); cleanupAsset(asset); - } else if (asset.behavior === "segmentation-rules") { - await runtimeHelpers.instantiate_segmentation_rules_asset(asset); - cleanupAsset(asset); } if (skipBufferByAssetTypes[asset.behavior]) { @@ -313,9 +306,6 @@ export function prepareAssets () { if (WasmEnableThreads) { convert_single_asset(modulesAssets, resources.jsModuleWorker, "js-module-threads"); } - if (config.globalizationMode == GlobalizationMode.Hybrid) { - convert_single_asset(modulesAssets, resources.jsModuleGlobalization, "js-module-globalization"); - } const addAsset = (asset: AssetEntryInternal, isCore: boolean) => { if (resources.fingerprinting && (asset.behavior == "assembly" || asset.behavior == "pdb" || asset.behavior == "resource")) { @@ -421,12 +411,6 @@ export function prepareAssets () { behavior: "icu", loadRemote: true }); - } else if (name.startsWith("segmentation-rules") && name.endsWith(".json")) { - assetsToLoad.push({ - name, - hash: resources.icu[name], - behavior: "segmentation-rules", - }); } } } diff --git a/src/mono/browser/runtime/loader/config.ts b/src/mono/browser/runtime/loader/config.ts index 24afa653772fa..3165672e6257e 100644 --- a/src/mono/browser/runtime/loader/config.ts +++ b/src/mono/browser/runtime/loader/config.ts @@ -71,9 +71,6 @@ function deep_merge_resources (target: ResourceGroups, source: ResourceGroups): if (providedResources.jsModuleNative !== undefined) { providedResources.jsModuleNative = { ...(target.jsModuleNative || {}), ...(providedResources.jsModuleNative || {}) }; } - if (providedResources.jsModuleGlobalization !== undefined) { - providedResources.jsModuleGlobalization = { ...(target.jsModuleGlobalization || {}), ...(providedResources.jsModuleGlobalization || {}) }; - } if (providedResources.jsModuleRuntime !== undefined) { providedResources.jsModuleRuntime = { ...(target.jsModuleRuntime || {}), ...(providedResources.jsModuleRuntime || {}) }; } @@ -124,7 +121,6 @@ export function normalizeConfig () { config.resources = config.resources || { assembly: {}, jsModuleNative: {}, - jsModuleGlobalization: {}, jsModuleWorker: {}, jsModuleRuntime: {}, wasmNative: {}, @@ -165,9 +161,6 @@ export function normalizeConfig () { case "js-module-threads": toMerge.jsModuleWorker = resource; break; - case "js-module-globalization": - toMerge.jsModuleGlobalization = resource; - break; case "js-module-runtime": toMerge.jsModuleRuntime = resource; break; diff --git a/src/mono/browser/runtime/loader/globals.ts b/src/mono/browser/runtime/loader/globals.ts index 91e0a89f2c0f9..5ef69d0e2e8ce 100644 --- a/src/mono/browser/runtime/loader/globals.ts +++ b/src/mono/browser/runtime/loader/globals.ts @@ -8,7 +8,7 @@ import { exceptions, simd } from "wasm-feature-detect"; import gitHash from "consts:gitHash"; -import type { DotnetModuleInternal, GlobalObjects, GlobalizationHelpers, LoaderHelpers, MonoConfigInternal, PThreadWorker, RuntimeHelpers } from "../types/internal"; +import type { DotnetModuleInternal, GlobalObjects, LoaderHelpers, MonoConfigInternal, PThreadWorker, RuntimeHelpers } from "../types/internal"; import type { MonoConfig, RuntimeAPI } from "../types"; import { assert_runtime_running, installUnhandledErrorHandler, is_exited, is_runtime_running, mono_exit } from "./exit"; import { assertIsControllablePromise, createPromiseController, getPromiseController } from "./promise-controller"; @@ -32,7 +32,6 @@ export const ENVIRONMENT_IS_WEB = typeof window == "object" || (ENVIRONMENT_IS_W export const ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE; export let runtimeHelpers: RuntimeHelpers = {} as any; -export let globalizationHelpers: GlobalizationHelpers = {} as any; export let loaderHelpers: LoaderHelpers = {} as any; export let exportedRuntimeAPI: RuntimeAPI = {} as any; export let INTERNAL: any = {}; @@ -49,7 +48,6 @@ export const globalObjectsRoot: GlobalObjects = { module: emscriptenModule, loaderHelpers, runtimeHelpers, - globalizationHelpers, api: exportedRuntimeAPI, } as any; @@ -63,7 +61,6 @@ export function setLoaderGlobals ( } _loaderModuleLoaded = true; runtimeHelpers = globalObjects.runtimeHelpers; - globalizationHelpers = globalObjects.globalizationHelpers; loaderHelpers = globalObjects.loaderHelpers; exportedRuntimeAPI = globalObjects.api; INTERNAL = globalObjects.internal; diff --git a/src/mono/browser/runtime/loader/icu.ts b/src/mono/browser/runtime/loader/icu.ts index 20b6a4578f0a3..1e90674a67dcc 100644 --- a/src/mono/browser/runtime/loader/icu.ts +++ b/src/mono/browser/runtime/loader/icu.ts @@ -26,11 +26,8 @@ export function init_globalization () { } const invariantEnv = "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"; - const hybridEnv = "DOTNET_SYSTEM_GLOBALIZATION_HYBRID"; const env_variables = loaderHelpers.config.environmentVariables!; - if (env_variables[hybridEnv] === undefined && loaderHelpers.config.globalizationMode === GlobalizationMode.Hybrid) { - env_variables[hybridEnv] = "1"; - } else if (env_variables[invariantEnv] === undefined && invariantMode) { + if (env_variables[invariantEnv] === undefined && invariantMode) { env_variables[invariantEnv] = "1"; } if (env_variables["TZ"] === undefined) { @@ -70,8 +67,6 @@ export function getIcuResourceName (config: MonoConfig): string | null { if (icuFiles.length >= 1) { return icuFiles[0]; } - } else if (config.globalizationMode === GlobalizationMode.Hybrid) { - icuFile = "icudt_hybrid.dat"; } else if (!culture || config.globalizationMode === GlobalizationMode.All) { icuFile = "icudt.dat"; } else if (config.globalizationMode === GlobalizationMode.Sharded) { diff --git a/src/mono/browser/runtime/loader/run.ts b/src/mono/browser/runtime/loader/run.ts index 6afe902c868c5..dc507d794d376 100644 --- a/src/mono/browser/runtime/loader/run.ts +++ b/src/mono/browser/runtime/loader/run.ts @@ -3,8 +3,8 @@ import BuildConfiguration from "consts:configuration"; -import { type MonoConfig, type DotnetHostBuilder, type DotnetModuleConfig, type RuntimeAPI, type LoadBootResourceCallback, GlobalizationMode } from "../types"; -import type { EmscriptenModuleInternal, RuntimeModuleExportsInternal, NativeModuleExportsInternal, HybridGlobalizationModuleExportsInternal, } from "../types/internal"; +import { type MonoConfig, type DotnetHostBuilder, type DotnetModuleConfig, type RuntimeAPI, type LoadBootResourceCallback } from "../types"; +import type { EmscriptenModuleInternal, RuntimeModuleExportsInternal, NativeModuleExportsInternal } from "../types/internal"; import { ENVIRONMENT_IS_WEB, ENVIRONMENT_IS_WORKER, emscriptenModule, exportedRuntimeAPI, globalObjectsRoot, monoConfig, mono_assert } from "./globals"; import { deep_merge_config, deep_merge_module, mono_wasm_load_config } from "./config"; @@ -12,7 +12,7 @@ import { installUnhandledErrorHandler, mono_exit, registerEmscriptenExitHandlers import { setup_proxy_console, mono_log_info, mono_log_debug } from "./logging"; import { mono_download_assets, preloadWorkers, prepareAssets, prepareAssetsWorker, resolve_single_asset_path, streamingCompileWasm } from "./assets"; import { detect_features_and_polyfill } from "./polyfills"; -import { runtimeHelpers, loaderHelpers, globalizationHelpers } from "./globals"; +import { runtimeHelpers, loaderHelpers } from "./globals"; import { init_globalization } from "./icu"; import { setupPreloadChannelToMainThread } from "./worker"; import { importLibraryInitializers, invokeLibraryInitializers } from "./libraryInitializers"; @@ -459,30 +459,11 @@ function importModules () { return [jsModuleRuntimePromise, jsModuleNativePromise]; } -async function getHybridModuleExports () : Promise { - let jsModuleHybridGlobalizationPromise: Promise | undefined = undefined; - // todo: move it for after runtime startup - const jsModuleHybridGlobalization = resolve_single_asset_path("js-module-globalization"); - if (typeof jsModuleHybridGlobalization.moduleExports === "object") { - jsModuleHybridGlobalizationPromise = jsModuleHybridGlobalization.moduleExports; - } else { - mono_log_debug(`Attempting to import '${jsModuleHybridGlobalization.resolvedUrl}' for ${jsModuleHybridGlobalization.name}`); - jsModuleHybridGlobalizationPromise = import(/*! webpackIgnore: true */jsModuleHybridGlobalization.resolvedUrl!); - } - const hybridModule = await jsModuleHybridGlobalizationPromise; - return hybridModule as any; -} - async function initializeModules (es6Modules: [RuntimeModuleExportsInternal, NativeModuleExportsInternal]) { const { initializeExports, initializeReplacements, configureRuntimeStartup, configureEmscriptenStartup, configureWorkerStartup, setRuntimeGlobals, passEmscriptenInternals } = es6Modules[0]; const { default: emscriptenFactory } = es6Modules[1]; setRuntimeGlobals(globalObjectsRoot); initializeExports(globalObjectsRoot); - if (loaderHelpers.config.globalizationMode === GlobalizationMode.Hybrid) { - const hybridModule = await getHybridModuleExports(); - const { initHybrid } = hybridModule; - initHybrid(globalizationHelpers, runtimeHelpers); - } await configureRuntimeStartup(emscriptenModule); loaderHelpers.runtimeModuleLoaded.promise_control.resolve(); diff --git a/src/mono/browser/runtime/rollup.config.js b/src/mono/browser/runtime/rollup.config.js index 31d3ed7e6e345..9b976e54cd98c 100644 --- a/src/mono/browser/runtime/rollup.config.js +++ b/src/mono/browser/runtime/rollup.config.js @@ -225,20 +225,6 @@ const typesConfig = { plugins: [dts()], onwarn: onwarn }; -const hybridGlobalizationConfig = { - input: "./hybrid-globalization/module-exports.ts", - output: [ - { - format: "es", - file: nativeBinDir + "/dotnet.globalization.js", - banner, - sourcemap: true, - sourcemapPathTransform, - } - ], - plugins: [...outputCodePlugins], - onwarn: onwarn -}; let diagnosticMockTypesConfig = undefined; @@ -294,7 +280,6 @@ const allConfigs = [ runtimeConfig, wasmImportsConfig, typesConfig, - hybridGlobalizationConfig, ] .concat(workerConfigs) .concat(diagnosticMockTypesConfig ? [diagnosticMockTypesConfig] : []); diff --git a/src/mono/browser/runtime/types/index.ts b/src/mono/browser/runtime/types/index.ts index c3658624dff19..eb6c12a1b3e2e 100644 --- a/src/mono/browser/runtime/types/index.ts +++ b/src/mono/browser/runtime/types/index.ts @@ -326,10 +326,6 @@ export type SingleAssetBehaviors = * The javascript module for emscripten. */ | "js-module-native" - /** - * The javascript module for hybrid globalization. - */ - | "js-module-globalization" /** * Typically blazor.boot.json */ @@ -338,10 +334,6 @@ export type SingleAssetBehaviors = * The debugging symbols */ | "symbols" - /** - * Load segmentation rules file for Hybrid Globalization. - */ - | "segmentation-rules"; export type AssetBehaviors = SingleAssetBehaviors | /** @@ -389,11 +381,7 @@ export const enum GlobalizationMode { /** * Use user defined icu file. */ - Custom = "custom", - /** - * Operate in hybrid globalization mode with small ICU files, using native platform functions. - */ - Hybrid = "hybrid" + Custom = "custom" } export type DotnetModuleConfig = { diff --git a/src/mono/browser/runtime/types/internal.ts b/src/mono/browser/runtime/types/internal.ts index 2b2792056a8d1..54f1125680627 100644 --- a/src/mono/browser/runtime/types/internal.ts +++ b/src/mono/browser/runtime/types/internal.ts @@ -239,7 +239,6 @@ export type RuntimeHelpers = { stringify_as_error_with_stack?: (error: any) => string, instantiate_asset: (asset: AssetEntry, url: string, bytes: Uint8Array) => void, instantiate_symbols_asset: (pendingAsset: AssetEntryInternal) => Promise, - instantiate_segmentation_rules_asset: (pendingAsset: AssetEntryInternal) => Promise, jiterpreter_dump_stats?: (concise?: boolean) => void, forceDisposeProxies: (disposeMethods: boolean, verbose: boolean) => void, dumpThreads: () => void, @@ -253,19 +252,6 @@ export type RuntimeHelpers = { setU16_local: (heap: Uint16Array, ptr: number, value: number) => void, setI32: (offset: MemOffset, value: number) => void, } -export type GlobalizationHelpers = { - - mono_wasm_change_case: (culture: number, cultureLength: number, src: number, srcLength: number, dst: number, dstLength: number, toUpper: number) => VoidPtr; - mono_wasm_compare_string: (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr) => VoidPtr; - mono_wasm_starts_with: (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr) => VoidPtr; - mono_wasm_ends_with: (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr) => VoidPtr; - mono_wasm_index_of: (culture: number, cultureLength: number, needlePtr: number, needleLength: number, srcPtr: number, srcLength: number, options: number, fromBeginning: number, resultPtr: Int32Ptr) => VoidPtr; - mono_wasm_get_calendar_info: (culture: number, cultureLength: number, calendarId: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr) => VoidPtr; - mono_wasm_get_culture_info: (culture: number, cultureLength: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr) => VoidPtr; - mono_wasm_get_first_day_of_week: (culture: number, cultureLength: number, resultPtr: Int32Ptr) => VoidPtr; - mono_wasm_get_first_week_of_year: (culture: number, cultureLength: number, resultPtr: Int32Ptr) => VoidPtr; - setSegmentationRulesFromJson: (json: string) => void; -} export type AOTProfilerOptions = { writeAt?: string, // should be in the format ::, default: 'WebAssembly.Runtime::StopProfile' @@ -317,7 +303,6 @@ export type GlobalObjects = { module: DotnetModuleInternal, loaderHelpers: LoaderHelpers, runtimeHelpers: RuntimeHelpers, - globalizationHelpers: GlobalizationHelpers, api: RuntimeAPI, }; export type EmscriptenReplacements = { @@ -517,10 +502,6 @@ export type NativeModuleExportsInternal = { default: (unificator: Function) => Promise } -export type HybridGlobalizationModuleExportsInternal = { - initHybrid: (gh: GlobalizationHelpers, rh: RuntimeHelpers) => void; -} - export type WeakRefInternal = WeakRef & { dispose?: () => void } diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets index 12a3e2121a8ab..1596acac19907 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets @@ -145,31 +145,23 @@ Copyright (c) .NET Foundation. All rights reserved. - - - <_RuntimePackDir>$(MicrosoftNetCoreAppRuntimePackDir) <_RuntimePackDir Condition="'$(_RuntimePackDir)' == ''">%(ResolvedRuntimePack.PackageDirectory) <_RuntimePackNativeDir>$([MSBuild]::NormalizeDirectory($(_RuntimePackDir), 'runtimes', 'browser-wasm', 'native')) - <_LoadCustomIcuData Condition="'$(InvariantGlobalization)' != 'true' AND '$(HybridGlobalization)' != 'true' AND '$(BlazorWebAssemblyLoadAllGlobalizationData)' != 'true' AND '$(BlazorIcuDataFileName)' != ''">true + <_LoadCustomIcuData Condition="'$(InvariantGlobalization)' != 'true' AND '$(BlazorWebAssemblyLoadAllGlobalizationData)' != 'true' AND '$(BlazorIcuDataFileName)' != ''">true <_LoadCustomIcuData Condition="'$(_LoadCustomIcuData)' == ''">false <_BlazorIcuDataFileName Condition="'$(_LoadCustomIcuData)' == 'true' AND Exists('$(BlazorIcuDataFileName)')">$(BlazorIcuDataFileName) <_BlazorIcuDataFileName Condition="'$(_LoadCustomIcuData)' == 'true' AND !Exists('$(BlazorIcuDataFileName)') AND !$([System.IO.Path]::IsPathRooted($(BlazorIcuDataFileName)))">$(_RuntimePackNativeDir)$(BlazorIcuDataFileName) - <_IsHybridGlobalization Condition="'$(InvariantGlobalization)' != 'true' AND '$(_LoadCustomIcuData)' != 'true'">$(HybridGlobalization) - <_IsHybridGlobalization Condition="'$(_IsHybridGlobalization)' == ''">false - <_BlazorWebAssemblyLoadAllGlobalizationData Condition="'$(InvariantGlobalization)' != 'true' AND '$(HybridGlobalization)' != 'true'">$(BlazorWebAssemblyLoadAllGlobalizationData) + <_BlazorWebAssemblyLoadAllGlobalizationData Condition="'$(InvariantGlobalization)' != 'true'">$(BlazorWebAssemblyLoadAllGlobalizationData) <_BlazorWebAssemblyLoadAllGlobalizationData Condition="'$(_BlazorWebAssemblyLoadAllGlobalizationData)' == ''">false - - - @@ -245,7 +237,6 @@ Copyright (c) .NET Foundation. All rights reserved. ProjectSatelliteAssemblies="@(IntermediateSatelliteAssembliesWithTargetPath)" TimeZoneSupport="$(_BlazorEnableTimeZoneSupport)" InvariantGlobalization="$(_WasmInvariantGlobalization)" - HybridGlobalization="$(_IsHybridGlobalization)" LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" CopySymbols="$(_WasmCopyOutputSymbolsToOutputDirectory)" OutputPath="$(OutputPath)" @@ -377,7 +368,6 @@ Copyright (c) .NET Foundation. All rights reserved. LazyLoadedAssemblies="@(BlazorWebAssemblyLazyLoad)" InvariantGlobalization="$(InvariantGlobalization)" LoadCustomIcuData="$(_LoadCustomIcuData)" - IsHybridGlobalization="$(_IsHybridGlobalization)" LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" StartupMemoryCache="$(_BlazorWebAssemblyStartupMemoryCache)" Jiterpreter="$(_BlazorWebAssemblyJiterpreter)" @@ -484,7 +474,6 @@ Copyright (c) .NET Foundation. All rights reserved. PublishPath="$(PublishDir)" WasmAotAssets="@(WasmNativeAsset)" InvariantGlobalization="$(_WasmInvariantGlobalization)" - HybridGlobalization="$(_IsHybridGlobalization)" LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" CopySymbols="$(CopyOutputSymbolsToPublishDirectory)" ExistingAssets="@(_WasmPublishPrefilteredAssets)" @@ -668,7 +657,6 @@ Copyright (c) .NET Foundation. All rights reserved. LazyLoadedAssemblies="@(BlazorWebAssemblyLazyLoad)" InvariantGlobalization="$(InvariantGlobalization)" LoadCustomIcuData="$(_LoadCustomIcuData)" - IsHybridGlobalization="$(_IsHybridGlobalization)" LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" StartupMemoryCache="$(_BlazorWebAssemblyStartupMemoryCache)" Jiterpreter="$(_BlazorWebAssemblyJiterpreter)" diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WasmFeatures.props b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WasmFeatures.props index 3743cddf79083..c429f998d9bef 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WasmFeatures.props +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WasmFeatures.props @@ -1,7 +1,6 @@ false - false false false true diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets index ec001114f2745..5c25ac9731da8 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets @@ -17,7 +17,6 @@ - diff --git a/src/mono/sample/wasm/Directory.Build.targets b/src/mono/sample/wasm/Directory.Build.targets index 8982f866eefe2..751980f96bc00 100644 --- a/src/mono/sample/wasm/Directory.Build.targets +++ b/src/mono/sample/wasm/Directory.Build.targets @@ -31,7 +31,6 @@ Outputs=" bin/$(Configuration)/AppBundle/dotnet.native.wasm; bin/$(Configuration)/AppBundle/dotnet.native.js; - bin/$(Configuration)/AppBundle/dotnet.globalization.js; bin/$(Configuration)/AppBundle/$(_WasmMainJSFileName); "> @@ -43,7 +42,6 @@ - diff --git a/src/mono/wasm/Wasm.Build.Tests/Common/GlobalizationMode.cs b/src/mono/wasm/Wasm.Build.Tests/Common/GlobalizationMode.cs index 250dbe7dc5b6b..b1687109bb4ae 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Common/GlobalizationMode.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Common/GlobalizationMode.cs @@ -10,5 +10,4 @@ public enum GlobalizationMode Invariant, // no icu FullIcu, // full icu data: icudt.dat is loaded Custom, // user set WasmIcuDataFileName/BlazorIcuDataFileName value and we are loading that file - Hybrid // reduced icu, missing data is provided by platform-native functions (web api for wasm) }; diff --git a/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs b/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs index 7bf3ce67c2c9b..56cd08e08eef7 100644 --- a/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs @@ -341,7 +341,6 @@ private string[] GetFilesMatchingNameConsideringFingerprinting(string filePath, Path.Combine(paths.BinFrameworkDir, "dotnet.native.wasm"), Path.Combine(paths.BinFrameworkDir, "dotnet.native.js"), - Path.Combine(paths.BinFrameworkDir, "dotnet.globalization.js"), }; if (isAOT) @@ -365,7 +364,6 @@ private string[] GetFilesMatchingNameConsideringFingerprinting(string filePath, dict["dotnet.js.map"]=(Path.Combine(paths.BinFrameworkDir, "dotnet.js.map"), true); dict["dotnet.runtime.js"]=(Path.Combine(paths.BinFrameworkDir, "dotnet.runtime.js"), true); dict["dotnet.runtime.js.map"]=(Path.Combine(paths.BinFrameworkDir, "dotnet.runtime.js.map"), true); - dict["dotnet.globalization.js"]=(Path.Combine(paths.BinFrameworkDir, "dotnet.globalization.js"), true); if (IsFingerprintingEnabled) { @@ -435,10 +433,6 @@ public void AssertIcuAssets(AssertBundleOptions assertOptions, BootJsonData boot case GlobalizationMode.FullIcu: expected.Add("icudt.dat"); break; - case GlobalizationMode.Hybrid: - expected.Add("icudt_hybrid.dat"); - expected.Add("segmentation-rules.json"); - break; case GlobalizationMode.Custom: if (string.IsNullOrEmpty(assertOptions.BuildOptions.CustomIcuFile)) throw new ArgumentException("WasmBuildTest is invalid, value for Custom globalization mode is required when GlobalizationMode=Custom."); @@ -457,8 +451,6 @@ public void AssertIcuAssets(AssertBundleOptions assertOptions, BootJsonData boot } IEnumerable actual = Directory.EnumerateFiles(assertOptions.BinFrameworkDir, "icudt*dat"); - if (assertOptions.BuildOptions.GlobalizationMode == GlobalizationMode.Hybrid) - actual = actual.Union(Directory.EnumerateFiles(assertOptions.BinFrameworkDir, "segmentation-rules*json")); if (IsFingerprintingEnabled) { diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs b/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs index c04d0bf50c2f6..89b99ca922fe1 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs @@ -31,7 +31,6 @@ protected override IReadOnlyDictionary GetAllKnownDotnetFilesToFin { "dotnet.js.map", false }, { "dotnet.native.js", true }, { "dotnet.native.js.symbols", false }, - { "dotnet.globalization.js", true }, { "dotnet.native.wasm", true }, { "dotnet.native.worker.mjs", true }, { "dotnet.runtime.js", true }, @@ -51,10 +50,6 @@ protected override IReadOnlySet GetDotNetFilesExpectedSet(AssertBundleOp { res.Add("dotnet.native.worker.mjs"); } - if (assertOptions.BuildOptions.GlobalizationMode is GlobalizationMode.Hybrid) - { - res.Add("dotnet.globalization.js"); - } if (!assertOptions.BuildOptions.IsPublish) { @@ -131,10 +126,6 @@ private void AssertBundle(AssertBundleOptions assertOptions) { nativeFilesToCheck.Add("dotnet.native.worker.mjs"); } - if (assertOptions.BuildOptions.GlobalizationMode == GlobalizationMode.Hybrid) - { - nativeFilesToCheck.Add("dotnet.globalization.js"); - } foreach (string nativeFilename in nativeFilesToCheck) { @@ -171,7 +162,7 @@ public void AssertWasmSdkBundle(Configuration config, MSBuildOptions buildOption } AssertBundle(config, buildOptions, isUsingWorkloads, isNativeBuild); } - + public BuildPaths GetBuildPaths(Configuration configuration, bool forPublish) { Assert.NotNull(ProjectDir); @@ -179,12 +170,12 @@ public BuildPaths GetBuildPaths(Configuration configuration, bool forPublish) string objDir = Path.Combine(ProjectDir, "obj", configStr, _defaultTargetFramework); string binDir = Path.Combine(ProjectDir, "bin", configStr, _defaultTargetFramework); string binFrameworkDir = GetBinFrameworkDir(configuration, forPublish, _defaultTargetFramework); - + string objWasmDir = Path.Combine(objDir, "wasm", forPublish ? "for-publish" : "for-build"); // for build: we should take from runtime pack? return new BuildPaths(objWasmDir, objDir, binDir, binFrameworkDir); } - + public override string GetBinFrameworkDir(Configuration config, bool forPublish, string framework, string? projectDir = null) { EnsureProjectDirIsSet(); @@ -194,4 +185,4 @@ public override string GetBinFrameworkDir(Configuration config, bool forPublish, return Path.Combine(basePath, BundleDirName, "_framework"); } -} \ No newline at end of file +} diff --git a/src/mono/wasm/build/WasmApp.Common.targets b/src/mono/wasm/build/WasmApp.Common.targets index c073f2e559300..be718671187a1 100644 --- a/src/mono/wasm/build/WasmApp.Common.targets +++ b/src/mono/wasm/build/WasmApp.Common.targets @@ -26,7 +26,6 @@ - $(AOTProfilePath) - profile data file to be used for profile-guided optimization - $(InvariantGlobalization) - Whether to disable ICU. Defaults to false. - $(InvariantTimezone) - Whether to disable Timezone database. Defaults to false. - - $(HybridGlobalization) - Whether to enable reduced ICU + native platform functions. Defaults to false and can be set only for InvariantGlobalization=false, WasmIncludeFullIcuData=false and empty WasmIcuDataFileName. - $(WasmResolveAssembliesBeforeBuild) - Resolve the assembly dependencies. Defaults to false - $(WasmAssemblySearchPaths) - used for resolving assembly dependencies diff --git a/src/mono/wasm/testassets/EntryPoints/HybridGlobalization.cs b/src/mono/wasm/testassets/EntryPoints/HybridGlobalization.cs deleted file mode 100644 index d318530fb26ff..0000000000000 --- a/src/mono/wasm/testassets/EntryPoints/HybridGlobalization.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Globalization; - -void WriteTestOutput(string output) => Console.WriteLine($"TestOutput -> {output}"); - -try -{ - CompareInfo compareInfo = new CultureInfo("es-ES").CompareInfo; - int shouldBeEqual = compareInfo.Compare("A\u0300", "\u00C0", CompareOptions.None); - if (shouldBeEqual != 0) - { - return 1; - } - int shouldThrow = compareInfo.Compare("A\u0300", "\u00C0", CompareOptions.IgnoreNonSpace); - WriteTestOutput($"Did not throw as expected but returned {shouldThrow} as a result. Using CompareOptions.IgnoreNonSpace option alone should be unavailable in HybridGlobalization mode."); -} -catch (PlatformNotSupportedException pnse) -{ - WriteTestOutput($"HybridGlobalization works, thrown exception as expected: {pnse}."); - return 42; -} -catch (Exception ex) -{ - WriteTestOutput($"HybridGlobalization failed, unexpected exception was thrown: {ex}."); - return 2; -} -return 3; diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs index b7bdbd752edb8..ecbc3e9c6b631 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs @@ -36,7 +36,6 @@ public static bool ShouldFilterCandidate( ITaskItem candidate, bool timezoneSupport, bool invariantGlobalization, - bool hybridGlobalization, bool loadFullICUData, bool copySymbols, string customIcuCandidateFilename, @@ -63,8 +62,6 @@ public static bool ShouldFilterCandidate( ".blat" when !timezoneSupport => "timezone support is not enabled.", ".dat" when invariantGlobalization && fileName.StartsWith("icudt") => "invariant globalization is enabled", ".dat" when loadFullICUData && fileName != "icudt" => "full ICU data is enabled", - ".dat" when hybridGlobalization && fileName != "icudt_hybrid" => "hybrid globalization is enabled", - ".json" when !hybridGlobalization && fileName == "segmentation-rules" => "segmentation-rules.json file is only used when hybrid globalization is enabled", ".dat" when !string.IsNullOrEmpty(customIcuCandidateFilename) && fileName != customIcuCandidateFilename => "custom icu file either from absolute path or from runtime pack path will be used", ".dat" when IsDefaultIcuMode() && !(icuShardsFromRuntimePack.Any(f => f == fileName)) => "automatic icu shard selection, based on application culture, is enabled", ".json" when fromMonoPackage && (fileName == "wasm-props" || fileName == "package") => $"{fileName}{extension} is not used by Blazor", @@ -83,7 +80,6 @@ public static bool ShouldFilterCandidate( bool IsDefaultIcuMode() => !invariantGlobalization && !loadFullICUData && - !hybridGlobalization && string.IsNullOrEmpty(customIcuCandidateFilename); } @@ -121,8 +117,6 @@ public static string GetCandidateRelativePath(ITaskItem candidate, bool fingerpr ("dotnet.runtime", ".js") => string.Concat(fileName, requiredFingerprint, extension), ("dotnet.native", ".js") => string.Concat(fileName, requiredFingerprint, extension), ("dotnet.native.worker", ".mjs") => string.Concat(fileName, requiredFingerprint, extension), - ("dotnet.globalization", ".js") => string.Concat(fileName, requiredFingerprint, extension), - ("segmentation-rules", ".json") => string.Concat(fileName, requiredFingerprint, extension), _ => string.Concat(fileName, extension) }; } diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs index b7559ddce6508..7c6c0836f4a2c 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs @@ -103,8 +103,6 @@ static void AddDictionary(StringBuilder sb, Dictionary? res) return bootConfig.resources.wasmSymbols ??= new(); else if (resourceName.StartsWith("icudt", StringComparison.OrdinalIgnoreCase)) return bootConfig.resources.icu ??= new(); - else if (resourceName.Equals("segmentation-rules.json", StringComparison.OrdinalIgnoreCase)) - return bootConfig.resources.icu ??= new(); else Log.LogError($"The resource '{resourceName}' is not recognized as any native asset"); diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonData.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonData.cs index 8df0f567148cb..32e09c9826c10 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonData.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonData.cs @@ -252,11 +252,6 @@ public enum GlobalizationMode : int /// Load custom icu file provided by the developer. /// Custom = 3, - - /// - /// Use the reduced icudt_hybrid.dat file - /// - Hybrid = 4, } [DataContract] diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs index cb070606f49c0..a9e9b91cb4e9e 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs @@ -40,9 +40,6 @@ public class ComputeWasmBuildAssets : Task [Required] public bool InvariantGlobalization { get; set; } - [Required] - public bool HybridGlobalization { get; set; } - [Required] public bool LoadFullICUData { get; set; } @@ -91,7 +88,7 @@ public override bool Execute() for (int i = 0; i < Candidates.Length; i++) { var candidate = Candidates[i]; - if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, HybridGlobalization, LoadFullICUData, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason)) + if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, LoadFullICUData, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason)) { Log.LogMessage(MessageImportance.Low, "Skipping asset '{0}' because '{1}'", candidate.ItemSpec, reason); filesToRemove.Add(candidate); @@ -235,7 +232,6 @@ private static void ApplyUniqueMetadataProperties(ITaskItem candidate) case ".js" when filename.StartsWith("dotnet"): case ".mjs" when filename.StartsWith("dotnet"): case ".dat" when filename.StartsWith("icudt"): - case ".json" when filename.StartsWith("segmentation-rules"): candidate.SetMetadata("AssetTraitName", "WasmResource"); candidate.SetMetadata("AssetTraitValue", "native"); break; diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs index 3ea146e92e6ed..ff555a8f8cba3 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs @@ -43,9 +43,6 @@ public class ComputeWasmPublishAssets : Task [Required] public bool InvariantGlobalization { get; set; } - [Required] - public bool HybridGlobalization { get; set; } - [Required] public bool LoadFullICUData { get; set; } @@ -663,7 +660,7 @@ private void GroupResolvedFilesToPublish( foreach (var candidate in resolvedFilesToPublish) { #pragma warning disable CA1864 // Prefer the 'IDictionary.TryAdd(TKey, TValue)' method. Dictionary.TryAdd() not available in .Net framework. - if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, HybridGlobalization, LoadFullICUData, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason)) + if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, LoadFullICUData, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason)) { Log.LogMessage(MessageImportance.Low, "Skipping asset '{0}' because '{1}'", candidate.ItemSpec, reason); if (!resolvedFilesToPublishToRemove.ContainsKey(candidate.ItemSpec)) diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs index eaaf55c20ae93..4453684d1b098 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs @@ -50,8 +50,6 @@ public class GenerateWasmBootJson : Task public bool LoadFullICUData { get; set; } - public bool IsHybridGlobalization { get; set; } - public bool LoadCustomIcuData { get; set; } public string InvariantGlobalization { get; set; } @@ -449,8 +447,6 @@ private GlobalizationMode GetGlobalizationMode() { if (string.Equals(InvariantGlobalization, "true", StringComparison.OrdinalIgnoreCase)) return GlobalizationMode.Invariant; - else if (IsHybridGlobalization) - return GlobalizationMode.Hybrid; else if (LoadFullICUData) return GlobalizationMode.All; else if (LoadCustomIcuData) diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs index 2bd56348e1a7d..2befd468f50d6 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -84,10 +84,6 @@ private GlobalizationMode GetGlobalizationMode() if (!string.IsNullOrEmpty(WasmIcuDataFileName)) return GlobalizationMode.Custom; - // Hybrid mode - if (HybridGlobalization) - return GlobalizationMode.Hybrid; - // If user requested to include full ICU data, use it if (WasmIncludeFullIcuData) return GlobalizationMode.All; @@ -173,9 +169,6 @@ protected override bool ExecuteInternal() if (!IncludeThreadsWorker && name == "dotnet.native.worker.mjs") continue; - if (!HybridGlobalization && name == "dotnet.globalization.js") - continue; - if (name == "dotnet.runtime.js.map" || name == "dotnet.js.map") { Log.LogMessage(MessageImportance.Low, $"Skipping {item.ItemSpec} from boot config"); diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs b/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs index 97bae1eaf3731..4b2271d7ae4a3 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs @@ -39,7 +39,6 @@ public abstract class WasmAppBuilderBaseTask : Task public string[] IcuDataFileNames { get; set; } = Array.Empty(); public ITaskItem[] SatelliteAssemblies { get; set; } = Array.Empty(); - public bool HybridGlobalization { get; set; } public bool InvariantGlobalization { get; set; } public ITaskItem[] FilesToIncludeInFileSystem { get; set; } = Array.Empty(); public ITaskItem[] ExtraFilesToDeploy { get; set; } = Array.Empty();